Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/native_NOTIOS/sun/awt/CDropTarget.m
38829 views
/*1* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425//#define DND_DEBUG TRUE2627#import "CDropTarget.h"28#import "AWTView.h"2930#import "sun_lwawt_macosx_CDropTarget.h"31#import "java_awt_dnd_DnDConstants.h"3233#import <JavaNativeFoundation/JavaNativeFoundation.h>34#import <JavaRuntimeSupport/JavaRuntimeSupport.h>35#include <objc/objc-runtime.h>363738#import "CDragSource.h"39#import "CDataTransferer.h"40#import "DnDUtilities.h"41#import "ThreadUtilities.h"424344static NSInteger sDraggingSequenceNumber = -1;45static NSDragOperation sDragOperation;46static NSDragOperation sUpdateOperation;47static jint sJavaDropOperation;48static NSPoint sDraggingLocation;49static BOOL sDraggingExited;50static BOOL sDraggingError;5152static NSUInteger sPasteboardItemsCount = 0;53static NSArray* sPasteboardTypes = nil;54static NSArray* sPasteboardData = nil;55static jlongArray sDraggingFormats = nil;5657static CDropTarget* sCurrentDropTarget;5859extern JNFClassInfo jc_CDropTargetContextPeer;6061@implementation CDropTarget6263+ (CDropTarget *) currentDropTarget {64return sCurrentDropTarget;65}6667- (id)init:(jobject)jdropTarget component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control68{69self = [super init];70DLog2(@"[CDropTarget init]: %@\n", self);7172fView = nil;73fComponent = nil;74fDropTarget = nil;75fDropTargetContextPeer = nil;767778if (control != nil) {79JNIEnv *env = [ThreadUtilities getJNIEnvUncached];80fComponent = JNFNewGlobalRef(env, jcomponent);81fDropTarget = JNFNewGlobalRef(env, jdropTarget);8283fView = [((AWTView *) control) retain];84[fView setDropTarget:self];858687} else {88// This would be an error.89[self release];90self = nil;91}92return self;93}9495// When [CDropTarget init] is called the ControlModel's fView may not have been set up yet. ControlModel96// (soon after) calls [CDropTarget controlModelControlValid] on the native event thread, once per CDropTarget,97// to let it know it's been set up now.98- (void)controlModelControlValid99{100// 9-30-02 Note: [Radar 3065621]101// List all known pasteboard types here (see AppKit's NSPasteboard.h)102// How to register for non-standard data types remains to be determined.103NSArray* dataTypes = [[NSArray alloc] initWithObjects:104NSStringPboardType,105NSFilenamesPboardType,106NSPostScriptPboardType,107NSTIFFPboardType,108NSPasteboardTypePNG,109NSRTFPboardType,110NSTabularTextPboardType,111NSFontPboardType,112NSRulerPboardType,113NSFileContentsPboardType,114NSColorPboardType,115NSRTFDPboardType,116NSHTMLPboardType,117NSURLPboardType,118NSPDFPboardType,119NSVCardPboardType,120NSFilesPromisePboardType,121[DnDUtilities javaPboardType],122(NSString*)kUTTypeJPEG,123nil];124125// Enable dragging events over this object:126[fView registerForDraggedTypes:dataTypes];127128[dataTypes release];129}130131- (void)releaseDraggingData132{133DLog2(@"[CDropTarget releaseDraggingData]: %@\n", self);134135// Release any old pasteboard types, data and properties:136[sPasteboardTypes release];137sPasteboardTypes = nil;138139[sPasteboardData release];140sPasteboardData = nil;141142if (sDraggingFormats != NULL) {143JNIEnv *env = [ThreadUtilities getJNIEnv];144JNFDeleteGlobalRef(env, sDraggingFormats);145sDraggingFormats = NULL;146}147148sPasteboardItemsCount = 0;149sDraggingSequenceNumber = -1;150}151152- (void)removeFromView:(JNIEnv *)env153{154DLog2(@"[CDropTarget removeFromView]: %@\n", self);155156// Remove this dragging destination from the view:157[((AWTView *) fView) setDropTarget:nil];158159// Clean up JNI refs160if (fComponent != NULL) {161JNFDeleteGlobalRef(env, fComponent);162fComponent = NULL;163}164if (fDropTarget != NULL) {165JNFDeleteGlobalRef(env, fDropTarget);166fDropTarget = NULL;167}168if (fDropTargetContextPeer != NULL) {169JNFDeleteGlobalRef(env, fDropTargetContextPeer);170fDropTargetContextPeer = NULL;171}172173[self release];174}175176- (void)dealloc177{178DLog2(@"[CDropTarget dealloc]: %@\n", self);179180if(sCurrentDropTarget == self) {181sCurrentDropTarget = nil;182}183184[fView release];185fView = nil;186187[super dealloc];188}189190- (NSInteger) getDraggingSequenceNumber191{192return sDraggingSequenceNumber;193}194195// Debugging help:196- (void)dumpPasteboard:(NSPasteboard*)pasteboard197{198NSArray* pasteboardTypes = [pasteboard types];199NSUInteger pasteboardItemsCount = [pasteboardTypes count];200NSUInteger i;201202// For each flavor on the pasteboard show the type, its data, and its property if there is one:203for (i = 0; i < pasteboardItemsCount; i++) {204NSString* pbType = [pasteboardTypes objectAtIndex:i];205CFShow(pbType);206207NSData* pbData = [pasteboard dataForType:pbType];208CFShow(pbData);209210if ([pbType hasPrefix:@"CorePasteboardFlavorType"] == NO) {211id pbDataProperty = [pasteboard propertyListForType:pbType];212CFShow(pbDataProperty);213}214}215}216217- (BOOL)copyDraggingTypes:(id<NSDraggingInfo>)sender218{219DLog2(@"[CDropTarget copyDraggingTypes]: %@\n", self);220JNIEnv* env = [ThreadUtilities getJNIEnv];221222// Release any old pasteboard data:223[self releaseDraggingData];224225NSPasteboard* pb = [sender draggingPasteboard];226sPasteboardTypes = [[pb types] retain];227sPasteboardItemsCount = [sPasteboardTypes count];228if (sPasteboardItemsCount == 0)229return FALSE;230231jlongArray formats = (*env)->NewLongArray(env, sPasteboardItemsCount);232if (formats == nil)233return FALSE;234235sDraggingFormats = (jlongArray) JNFNewGlobalRef(env, formats);236(*env)->DeleteLocalRef(env, formats);237if (sDraggingFormats == nil)238return FALSE;239240jboolean isCopy;241jlong* jformats = (*env)->GetLongArrayElements(env, sDraggingFormats, &isCopy);242if (jformats == nil) {243return FALSE;244}245246// Copy all data formats and properties. In case of properties, if they are nil, we need to use247// a special NilProperty since [NSArray addObject] would crash on adding a nil object.248DLog2(@"[CDropTarget copyDraggingTypes]: typesCount = %lu\n", (unsigned long) sPasteboardItemsCount);249NSUInteger i;250for (i = 0; i < sPasteboardItemsCount; i++) {251NSString* pbType = [sPasteboardTypes objectAtIndex:i];252DLog3(@"[CDropTarget copyDraggingTypes]: type[%lu] = %@\n", (unsigned long) i, pbType);253254// 01-10-03 Note: until we need data properties for doing something useful don't copy them.255// They're often copies of their flavor's data and copying them for all available pasteboard flavors256// (which are often auto-translation of one another) can be a significant time/space hit.257258// If this is a remote object type (not a pre-defined format) register it with the pasteboard:259jformats[i] = indexForFormat(pbType);260if (jformats[i] == -1 && [pbType hasPrefix:@"JAVA_DATAFLAVOR:application/x-java-remote-object;"])261jformats[i] = registerFormatWithPasteboard(pbType);262}263264(*env)->ReleaseLongArrayElements(env, sDraggingFormats, jformats, JNI_COMMIT);265266return TRUE;267}268269- (BOOL)copyDraggingData:(id<NSDraggingInfo>)sender270{271DLog2(@"[CDropTarget copyDraggingData]: %@\n", self);272273sPasteboardData = [[NSMutableArray alloc] init];274if (sPasteboardData == nil)275return FALSE;276277// Copy all data items to a safe place since the pasteboard may go away before we'll need them:278NSPasteboard* pb = [sender draggingPasteboard];279NSUInteger i;280for (i = 0; i < sPasteboardItemsCount; i++) {281// Get a type and its data and save the data:282NSString* pbType = [sPasteboardTypes objectAtIndex:i];283// 01-10-03 Note: copying only NS-type data (until Java-specified types can make it through the AppKit)284// would be a good idea since we can't do anything with those CoreFoundation unknown types anyway.285// But I'm worried that it would break something in Fuller so I'm leaving this here as a reminder,286// to be evaluated later.287//id pbData = [pbType hasPrefix:@"NS"] ? [pb dataForType:pbType] : nil; // Copy only NS-type data!288id pbData = [pb dataForType:pbType];289290// If the data is null we can't store it in the array - an exception would be thrown.291// We use the special object NSNull instead which is kosher.292if (pbData == nil)293pbData = [NSNull null];294295[((NSMutableArray*) sPasteboardData) addObject:pbData];296}297298return TRUE;299}300301- (NSData*) getDraggingDataForURL:(NSData*)data302{303NSData* result = nil;304305// Convert data into a property list if possible:306NSPropertyListFormat propertyListFormat;307NSString* errorString = nil;308id propertyList = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable309format:&propertyListFormat errorDescription:&errorString];310311// URL types have only a single URL string in an array:312if (propertyList != nil && errorString == nil && [propertyList isKindOfClass:[NSArray class]]) {313NSArray* array = (NSArray*) propertyList;314if ([array count] > 0) {315NSString* url = (NSString*) [array objectAtIndex:0];316if (url != nil && [url length] > 0)317result = [url dataUsingEncoding:[url fastestEncoding]];318}319}320321return result;322}323324- (jobject) copyDraggingDataForFormat:(jlong)format325{326JNIEnv* env = [ThreadUtilities getJNIEnvUncached]; // Join the main thread by requesting uncached environment327328NSData* data = nil;329330// Convert the Java format (datatransferer int index) to a pasteboard format (NSString):331NSString* pbType = formatForIndex(format);332if ([sPasteboardTypes containsObject:pbType]) {333NSUInteger dataIndex = [sPasteboardTypes indexOfObject:pbType];334data = [sPasteboardData objectAtIndex:dataIndex];335336if ((id) data == [NSNull null])337data = nil;338339// format == 8 (CF_URL in CDataTransferer): we need a URL-to-String conversion:340else if ([pbType isEqualToString:@"Apple URL pasteboard type"])341data = [self getDraggingDataForURL:data];342}343344// Get NS data:345char* dataBytes = (data != nil) ? (char*) [data bytes] : "Unsupported type";346NSUInteger dataLength = (data != nil) ? [data length] : sizeof("Unsupported type");347348// Create a global byte array:349jbyteArray lbyteArray = (*env)->NewByteArray(env, dataLength);350if (lbyteArray == nil)351return nil;352jbyteArray gbyteArray = (jbyteArray) JNFNewGlobalRef(env, lbyteArray);353(*env)->DeleteLocalRef(env, lbyteArray);354if (gbyteArray == nil)355return nil;356357// Get byte array elements:358jboolean isCopy;359jbyte* jbytes = (*env)->GetByteArrayElements(env, gbyteArray, &isCopy);360if (jbytes == nil)361return nil;362363// Copy data to byte array and release elements:364memcpy(jbytes, dataBytes, dataLength);365(*env)->ReleaseByteArrayElements(env, gbyteArray, jbytes, JNI_COMMIT);366367// In case of an error make sure to return nil:368if ((*env)->ExceptionOccurred(env)) {369(*env)->ExceptionDescribe(env);370gbyteArray = nil;371}372373return gbyteArray;374}375376- (void)safeReleaseDraggingData:(NSNumber *)arg377{378jlong draggingSequenceNumber = [arg longLongValue];379380// Make sure dragging data is released only if no new drag is under way. If a new drag381// has been initiated it has released the old dragging data already. This has to be called382// on the native event thread - otherwise we'd need to start synchronizing.383if (draggingSequenceNumber == sDraggingSequenceNumber)384[self releaseDraggingData];385}386387- (void)javaDraggingEnded:(jlong)draggingSequenceNumber success:(BOOL)jsuccess action:(jint)jdropaction388{389NSNumber *draggingSequenceNumberID = [NSNumber numberWithLongLong:draggingSequenceNumber];390// Report back actual Swing success, not what AppKit thinks391sDraggingError = !jsuccess;392sDragOperation = [DnDUtilities mapJavaDragOperationToNS:jdropaction];393394// Release dragging data if any when Java's AWT event thread is all finished.395// Make sure dragging data is released on the native event thread.396[ThreadUtilities performOnMainThread:@selector(safeReleaseDraggingData:) on:self withObject:draggingSequenceNumberID waitUntilDone:NO];397}398399- (jint)currentJavaActions {400return [DnDUtilities mapNSDragOperationToJava:sUpdateOperation];401}402403/******************************** BEGIN NSDraggingDestination Interface ********************************/404405406// Private API to calculate the current Java actions407- (void) calculateCurrentSourceActions:(jint *)actions dropAction:(jint *)dropAction408{409// Get the raw (unmodified by keys) source actions410id jrsDrag = objc_lookUpClass("JRSDrag");411if (jrsDrag != nil) {412NSDragOperation rawDragActions = (NSDragOperation) [jrsDrag performSelector:@selector(currentAllowableActions)];413if (rawDragActions != NSDragOperationNone) {414// Both actions and dropAction default to the rawActions415*actions = [DnDUtilities mapNSDragOperationMaskToJava:rawDragActions];416*dropAction = *actions;417418// Get the current key modifiers.419NSUInteger dragModifiers = (NSUInteger) [jrsDrag performSelector:@selector(currentModifiers)];420// Either the drop action is narrowed as per Java rules (MOVE, COPY, LINK, NONE) or by the drag modifiers421if (dragModifiers) {422// Get the user selected operation based on the drag modifiers, then return the intersection423NSDragOperation currentOp = [DnDUtilities nsDragOperationForModifiers:dragModifiers];424NSDragOperation allowedOp = rawDragActions & currentOp;425426*dropAction = [DnDUtilities mapNSDragOperationToJava:allowedOp];427}428}429}430*dropAction = [DnDUtilities narrowJavaDropActions:*dropAction];431}432433- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender434{435DLog2(@"[CDropTarget draggingEntered]: %@\n", self);436437sCurrentDropTarget = self;438439JNIEnv* env = [ThreadUtilities getJNIEnv];440NSInteger draggingSequenceNumber = [sender draggingSequenceNumber];441442// Set the initial drag operation return value:443NSDragOperation dragOp = NSDragOperationNone;444sJavaDropOperation = java_awt_dnd_DnDConstants_ACTION_NONE;445446// We could probably special-case some stuff if drag and drop objects match:447//if ([sender dragSource] == fView)448449if (draggingSequenceNumber != sDraggingSequenceNumber) {450sDraggingSequenceNumber = draggingSequenceNumber;451sDraggingError = FALSE;452453// Delete any drop target context peer left over from a previous drag:454if (fDropTargetContextPeer != NULL) {455JNFDeleteGlobalRef(env, fDropTargetContextPeer);456fDropTargetContextPeer = NULL;457}458459// Look up the CDropTargetContextPeer class:460JNF_STATIC_MEMBER_CACHE(getDropTargetContextPeerMethod, jc_CDropTargetContextPeer, "getDropTargetContextPeer", "()Lsun/lwawt/macosx/CDropTargetContextPeer;");461if (sDraggingError == FALSE) {462// Create a new drop target context peer:463jobject dropTargetContextPeer = JNFCallStaticObjectMethod(env, getDropTargetContextPeerMethod);464465if (dropTargetContextPeer != nil) {466fDropTargetContextPeer = JNFNewGlobalRef(env, dropTargetContextPeer);467(*env)->DeleteLocalRef(env, dropTargetContextPeer);468}469}470471// Get dragging types (dragging data is only copied if dropped):472if (sDraggingError == FALSE && [self copyDraggingTypes:sender] == FALSE)473sDraggingError = TRUE;474}475476if (sDraggingError == FALSE) {477sDraggingExited = FALSE;478sDraggingLocation = [sender draggingLocation];479NSPoint javaLocation = [fView convertPoint:sDraggingLocation fromView:nil];480javaLocation.y = fView.window.frame.size.height - javaLocation.y;481482DLog5(@"+ dragEnter: loc native %f, %f, java %f, %f\n", sDraggingLocation.x, sDraggingLocation.y, javaLocation.x, javaLocation.y);483484////////// BEGIN Calculate the current drag actions //////////485jint actions = java_awt_dnd_DnDConstants_ACTION_NONE;486jint dropAction = actions;487488[self calculateCurrentSourceActions:&actions dropAction:&dropAction];489490sJavaDropOperation = dropAction;491////////// END Calculate the current drag actions //////////492493jlongArray formats = sDraggingFormats;494495JNF_MEMBER_CACHE(handleEnterMessageMethod, jc_CDropTargetContextPeer, "handleEnterMessage", "(Ljava/awt/Component;IIII[JJ)I");496if (sDraggingError == FALSE) {497// Double-casting self gets rid of 'different size' compiler warning:498// AWT_THREADING Safe (CToolkitThreadBlockedHandler)499actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod,500fComponent, (jint) javaLocation.x, (jint) javaLocation.y,501dropAction, actions, formats, ptr_to_jlong(self));502}503504if (sDraggingError == FALSE) {505// Initialize drag operation:506sDragOperation = NSDragOperationNone;507508// Map Java actions back to NSDragOperation.509// 1-6-03 Note: if the entry point of this CDropTarget isn't covered by a droppable component510// (as can be the case with lightweight children) we must not return NSDragOperationNone511// since that would prevent dropping into any of the contained drop targets.512// Unfortunately there is no easy way to test this so we just test actions and override them513// with GENERIC if necessary. Proper drag operations will be returned by draggingUpdated: which is514// called right away, taking care of setting the right cursor and snap-back action.515dragOp = ((actions != java_awt_dnd_DnDConstants_ACTION_NONE) ?516[DnDUtilities mapJavaDragOperationToNS:dropAction] : NSDragOperationGeneric);517518// Remember the dragOp for no-op'd update messages:519sUpdateOperation = dragOp;520}521}522523// 9-11-02 Note: the native event thread would not handle an exception gracefully:524//if (sDraggingError == TRUE)525// [NSException raise:NSGenericException format:@"[CDropTarget draggingEntered] failed."];526527DLog2(@"[CDropTarget draggingEntered]: returning %lu\n", (unsigned long) dragOp);528529return dragOp;530}531532- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender533{534//DLog2(@"[CDropTarget draggingUpdated]: %@\n", self);535536sCurrentDropTarget = self;537538// Set the initial drag operation return value:539NSDragOperation dragOp = (sDraggingError == FALSE ? sUpdateOperation : NSDragOperationNone);540541// There are two things we would be interested in:542// a) mouse pointer has moved543// b) drag actions (key modifiers) have changed544545NSPoint draggingLocation = [sender draggingLocation];546JNIEnv* env = [ThreadUtilities getJNIEnv];547548BOOL notifyJava = FALSE;549550// a) mouse pointer has moved:551if (NSEqualPoints(draggingLocation, sDraggingLocation) == FALSE) {552//DLog2(@"[CDropTarget draggingUpdated]: mouse moved, %@\n", self);553sDraggingLocation = draggingLocation;554notifyJava = TRUE;555}556557// b) drag actions (key modifiers) have changed (handleMotionMessage() will do proper notifications):558////////// BEGIN Calculate the current drag actions //////////559jint actions = java_awt_dnd_DnDConstants_ACTION_NONE;560jint dropAction = actions;561562[self calculateCurrentSourceActions:&actions dropAction:&dropAction];563564if (sJavaDropOperation != dropAction) {565sJavaDropOperation = dropAction;566notifyJava = TRUE;567}568////////// END Calculate the current drag actions //////////569570jint userAction = dropAction;571572// Should we notify Java things have changed?573if (sDraggingError == FALSE && notifyJava) {574NSPoint javaLocation = [fView convertPoint:sDraggingLocation fromView:nil];575javaLocation.y = fView.window.frame.size.height - javaLocation.y;576//DLog5(@" : dragMoved: loc native %f, %f, java %f, %f\n", sDraggingLocation.x, sDraggingLocation.y, javaLocation.x, javaLocation.y);577578jlongArray formats = sDraggingFormats;579580JNF_MEMBER_CACHE(handleMotionMessageMethod, jc_CDropTargetContextPeer, "handleMotionMessage", "(Ljava/awt/Component;IIII[JJ)I");581if (sDraggingError == FALSE) {582DLog3(@" >> posting handleMotionMessage, point %f, %f", javaLocation.x, javaLocation.y);583userAction = JNFCallIntMethod(env, fDropTargetContextPeer, handleMotionMessageMethod, fComponent, (jint) javaLocation.x, (jint) javaLocation.y, dropAction, actions, formats, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler)584}585586if (sDraggingError == FALSE) {587dragOp = [DnDUtilities mapJavaDragOperationToNS:userAction];588589// Remember the dragOp for no-op'd update messages:590sUpdateOperation = dragOp;591} else {592dragOp = NSDragOperationNone;593}594}595596DLog2(@"[CDropTarget draggingUpdated]: returning %lu\n", (unsigned long) dragOp);597598return dragOp;599}600601- (void)draggingExited:(id<NSDraggingInfo>)sender602{603DLog2(@"[CDropTarget draggingExited]: %@\n", self);604605sCurrentDropTarget = nil;606607JNIEnv* env = [ThreadUtilities getJNIEnv];608609if (sDraggingExited == FALSE && sDraggingError == FALSE) {610JNF_MEMBER_CACHE(handleExitMessageMethod, jc_CDropTargetContextPeer, "handleExitMessage", "(Ljava/awt/Component;J)V");611if (sDraggingError == FALSE) {612DLog3(@" - dragExit: loc native %f, %f\n", sDraggingLocation.x, sDraggingLocation.y);613// AWT_THREADING Safe (CToolkitThreadBlockedHandler)614JNFCallVoidMethod(env, fDropTargetContextPeer,615handleExitMessageMethod, fComponent, ptr_to_jlong(self));616}617618// 5-27-03 Note: [Radar 3270455]619// -draggingExited: can be called both by the AppKit and by -performDragOperation: but shouldn't execute620// twice per drop since cleanup code like that in swing/plaf/basic/BasicDropTargetListener would throw NPEs.621sDraggingExited = TRUE;622}623624DLog(@"[CDropTarget draggingExited]: returning.\n");625}626627- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender628{629DLog2(@"[CDropTarget prepareForDragOperation]: %@\n", self);630DLog2(@"[CDropTarget prepareForDragOperation]: returning %@\n", (sDraggingError ? @"NO" : @"YES"));631632return sDraggingError ? NO : YES;633}634635- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender636{637DLog2(@"[CDropTarget performDragOperation]: %@\n", self);638639sCurrentDropTarget = nil;640641JNIEnv* env = [ThreadUtilities getJNIEnv];642643// Now copy dragging data:644if (sDraggingError == FALSE && [self copyDraggingData:sender] == FALSE)645sDraggingError = TRUE;646647if (sDraggingError == FALSE) {648sDraggingLocation = [sender draggingLocation];649NSPoint javaLocation = [fView convertPoint:sDraggingLocation fromView:nil];650// The y coordinate that comes in the NSDraggingInfo seems to be reversed - probably651// has to do something with the type of view it comes to.652// This is the earliest place where we can correct it.653javaLocation.y = fView.window.frame.size.height - javaLocation.y;654655jint actions = [DnDUtilities mapNSDragOperationMaskToJava:[sender draggingSourceOperationMask]];656jint dropAction = sJavaDropOperation;657658jlongArray formats = sDraggingFormats;659660JNF_MEMBER_CACHE(handleDropMessageMethod, jc_CDropTargetContextPeer, "handleDropMessage", "(Ljava/awt/Component;IIII[JJ)V");661662if (sDraggingError == FALSE) {663JNFCallVoidMethod(env, fDropTargetContextPeer, handleDropMessageMethod, fComponent, (jint) javaLocation.x, (jint) javaLocation.y, dropAction, actions, formats, ptr_to_jlong(self)); // AWT_THREADING Safe (event)664}665666if (sDraggingError == FALSE) {667JNF_MEMBER_CACHE(flushEventsMethod, jc_CDropTargetContextPeer, "flushEvents", "(Ljava/awt/Component;)V");668if (sDraggingError == FALSE) {669JNFCallVoidMethod(env, fDropTargetContextPeer, flushEventsMethod, fComponent); // AWT_THREADING Safe (AWTRunLoopMode)670}671}672} else {673// 8-19-03 Note: [Radar 3368754]674// draggingExited: is not called after a drop - we must do that here ... but only in case675// of an error, instead of drop(). Otherwise we get twice the cleanup in shared code.676[self draggingExited:sender];677}678679// TODO:BG680// [(id)sender _setLastDragDestinationOperation:sDragOperation];681682683DLog2(@"[CDropTarget performDragOperation]: returning %@\n", (sDraggingError ? @"NO" : @"YES"));684685return !sDraggingError;686}687688- (void)concludeDragOperation:(id<NSDraggingInfo>)sender689{690sCurrentDropTarget = nil;691692DLog2(@"[CDropTarget concludeDragOperation]: %@\n", self);693DLog(@"[CDropTarget concludeDragOperation]: returning.\n");694}695696// 9-11-02 Note: draggingEnded is not yet implemented by the AppKit.697- (void)draggingEnded:(id<NSDraggingInfo>)sender698{699sCurrentDropTarget = nil;700701DLog2(@"[CDropTarget draggingEnded]: %@\n", self);702DLog(@"[CDropTarget draggingEnded]: returning.\n");703}704705/******************************** END NSDraggingDestination Interface ********************************/706707@end708709710/*711* Class: sun_lwawt_macosx_CDropTarget712* Method: createNativeDropTarget713* Signature: (Ljava/awt/dnd/DropTarget;Ljava/awt/Component;Ljava/awt/peer/ComponentPeer;J)J714*/715JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDropTarget_createNativeDropTarget716(JNIEnv *env, jobject jthis, jobject jdroptarget, jobject jcomponent, jobject jpeer, jlong jnativepeer)717{718CDropTarget* dropTarget = nil;719720JNF_COCOA_ENTER(env);721id controlObj = (id) jlong_to_ptr(jnativepeer);722dropTarget = [[CDropTarget alloc] init:jdroptarget component:jcomponent peer:jpeer control:controlObj];723JNF_COCOA_EXIT(env);724725return ptr_to_jlong(dropTarget);726}727728/*729* Class: sun_lwawt_macosx_CDropTarget730* Method: releaseNativeDropTarget731* Signature: (J)V732*/733JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDropTarget_releaseNativeDropTarget734(JNIEnv *env, jobject jthis, jlong nativeDropTargetVal)735{736id dropTarget = (id)jlong_to_ptr(nativeDropTargetVal);737738JNF_COCOA_ENTER(env);739[dropTarget removeFromView:env];740JNF_COCOA_EXIT(env);741}742743744