Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/native_NOTIOS/sun/awt/CDropTarget.m
38829 views
1
/*
2
* Copyright (c) 2011, 2016, 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
//#define DND_DEBUG TRUE
27
28
#import "CDropTarget.h"
29
#import "AWTView.h"
30
31
#import "sun_lwawt_macosx_CDropTarget.h"
32
#import "java_awt_dnd_DnDConstants.h"
33
34
#import <JavaNativeFoundation/JavaNativeFoundation.h>
35
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
36
#include <objc/objc-runtime.h>
37
38
39
#import "CDragSource.h"
40
#import "CDataTransferer.h"
41
#import "DnDUtilities.h"
42
#import "ThreadUtilities.h"
43
44
45
static NSInteger sDraggingSequenceNumber = -1;
46
static NSDragOperation sDragOperation;
47
static NSDragOperation sUpdateOperation;
48
static jint sJavaDropOperation;
49
static NSPoint sDraggingLocation;
50
static BOOL sDraggingExited;
51
static BOOL sDraggingError;
52
53
static NSUInteger sPasteboardItemsCount = 0;
54
static NSArray* sPasteboardTypes = nil;
55
static NSArray* sPasteboardData = nil;
56
static jlongArray sDraggingFormats = nil;
57
58
static CDropTarget* sCurrentDropTarget;
59
60
extern JNFClassInfo jc_CDropTargetContextPeer;
61
62
@implementation CDropTarget
63
64
+ (CDropTarget *) currentDropTarget {
65
return sCurrentDropTarget;
66
}
67
68
- (id)init:(jobject)jdropTarget component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control
69
{
70
self = [super init];
71
DLog2(@"[CDropTarget init]: %@\n", self);
72
73
fView = nil;
74
fComponent = nil;
75
fDropTarget = nil;
76
fDropTargetContextPeer = nil;
77
78
79
if (control != nil) {
80
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
81
fComponent = JNFNewGlobalRef(env, jcomponent);
82
fDropTarget = JNFNewGlobalRef(env, jdropTarget);
83
84
fView = [((AWTView *) control) retain];
85
[fView setDropTarget:self];
86
87
88
} else {
89
// This would be an error.
90
[self release];
91
self = nil;
92
}
93
return self;
94
}
95
96
// When [CDropTarget init] is called the ControlModel's fView may not have been set up yet. ControlModel
97
// (soon after) calls [CDropTarget controlModelControlValid] on the native event thread, once per CDropTarget,
98
// to let it know it's been set up now.
99
- (void)controlModelControlValid
100
{
101
// 9-30-02 Note: [Radar 3065621]
102
// List all known pasteboard types here (see AppKit's NSPasteboard.h)
103
// How to register for non-standard data types remains to be determined.
104
NSArray* dataTypes = [[NSArray alloc] initWithObjects:
105
NSStringPboardType,
106
NSFilenamesPboardType,
107
NSPostScriptPboardType,
108
NSTIFFPboardType,
109
NSPasteboardTypePNG,
110
NSRTFPboardType,
111
NSTabularTextPboardType,
112
NSFontPboardType,
113
NSRulerPboardType,
114
NSFileContentsPboardType,
115
NSColorPboardType,
116
NSRTFDPboardType,
117
NSHTMLPboardType,
118
NSURLPboardType,
119
NSPDFPboardType,
120
NSVCardPboardType,
121
NSFilesPromisePboardType,
122
[DnDUtilities javaPboardType],
123
(NSString*)kUTTypeJPEG,
124
nil];
125
126
// Enable dragging events over this object:
127
[fView registerForDraggedTypes:dataTypes];
128
129
[dataTypes release];
130
}
131
132
- (void)releaseDraggingData
133
{
134
DLog2(@"[CDropTarget releaseDraggingData]: %@\n", self);
135
136
// Release any old pasteboard types, data and properties:
137
[sPasteboardTypes release];
138
sPasteboardTypes = nil;
139
140
[sPasteboardData release];
141
sPasteboardData = nil;
142
143
if (sDraggingFormats != NULL) {
144
JNIEnv *env = [ThreadUtilities getJNIEnv];
145
JNFDeleteGlobalRef(env, sDraggingFormats);
146
sDraggingFormats = NULL;
147
}
148
149
sPasteboardItemsCount = 0;
150
sDraggingSequenceNumber = -1;
151
}
152
153
- (void)removeFromView:(JNIEnv *)env
154
{
155
DLog2(@"[CDropTarget removeFromView]: %@\n", self);
156
157
// Remove this dragging destination from the view:
158
[((AWTView *) fView) setDropTarget:nil];
159
160
// Clean up JNI refs
161
if (fComponent != NULL) {
162
JNFDeleteGlobalRef(env, fComponent);
163
fComponent = NULL;
164
}
165
if (fDropTarget != NULL) {
166
JNFDeleteGlobalRef(env, fDropTarget);
167
fDropTarget = NULL;
168
}
169
if (fDropTargetContextPeer != NULL) {
170
JNFDeleteGlobalRef(env, fDropTargetContextPeer);
171
fDropTargetContextPeer = NULL;
172
}
173
174
[self release];
175
}
176
177
- (void)dealloc
178
{
179
DLog2(@"[CDropTarget dealloc]: %@\n", self);
180
181
if(sCurrentDropTarget == self) {
182
sCurrentDropTarget = nil;
183
}
184
185
[fView release];
186
fView = nil;
187
188
[super dealloc];
189
}
190
191
- (NSInteger) getDraggingSequenceNumber
192
{
193
return sDraggingSequenceNumber;
194
}
195
196
// Debugging help:
197
- (void)dumpPasteboard:(NSPasteboard*)pasteboard
198
{
199
NSArray* pasteboardTypes = [pasteboard types];
200
NSUInteger pasteboardItemsCount = [pasteboardTypes count];
201
NSUInteger i;
202
203
// For each flavor on the pasteboard show the type, its data, and its property if there is one:
204
for (i = 0; i < pasteboardItemsCount; i++) {
205
NSString* pbType = [pasteboardTypes objectAtIndex:i];
206
CFShow(pbType);
207
208
NSData* pbData = [pasteboard dataForType:pbType];
209
CFShow(pbData);
210
211
if ([pbType hasPrefix:@"CorePasteboardFlavorType"] == NO) {
212
id pbDataProperty = [pasteboard propertyListForType:pbType];
213
CFShow(pbDataProperty);
214
}
215
}
216
}
217
218
- (BOOL)copyDraggingTypes:(id<NSDraggingInfo>)sender
219
{
220
DLog2(@"[CDropTarget copyDraggingTypes]: %@\n", self);
221
JNIEnv* env = [ThreadUtilities getJNIEnv];
222
223
// Release any old pasteboard data:
224
[self releaseDraggingData];
225
226
NSPasteboard* pb = [sender draggingPasteboard];
227
sPasteboardTypes = [[pb types] retain];
228
sPasteboardItemsCount = [sPasteboardTypes count];
229
if (sPasteboardItemsCount == 0)
230
return FALSE;
231
232
jlongArray formats = (*env)->NewLongArray(env, sPasteboardItemsCount);
233
if (formats == nil)
234
return FALSE;
235
236
sDraggingFormats = (jlongArray) JNFNewGlobalRef(env, formats);
237
(*env)->DeleteLocalRef(env, formats);
238
if (sDraggingFormats == nil)
239
return FALSE;
240
241
jboolean isCopy;
242
jlong* jformats = (*env)->GetLongArrayElements(env, sDraggingFormats, &isCopy);
243
if (jformats == nil) {
244
return FALSE;
245
}
246
247
// Copy all data formats and properties. In case of properties, if they are nil, we need to use
248
// a special NilProperty since [NSArray addObject] would crash on adding a nil object.
249
DLog2(@"[CDropTarget copyDraggingTypes]: typesCount = %lu\n", (unsigned long) sPasteboardItemsCount);
250
NSUInteger i;
251
for (i = 0; i < sPasteboardItemsCount; i++) {
252
NSString* pbType = [sPasteboardTypes objectAtIndex:i];
253
DLog3(@"[CDropTarget copyDraggingTypes]: type[%lu] = %@\n", (unsigned long) i, pbType);
254
255
// 01-10-03 Note: until we need data properties for doing something useful don't copy them.
256
// They're often copies of their flavor's data and copying them for all available pasteboard flavors
257
// (which are often auto-translation of one another) can be a significant time/space hit.
258
259
// If this is a remote object type (not a pre-defined format) register it with the pasteboard:
260
jformats[i] = indexForFormat(pbType);
261
if (jformats[i] == -1 && [pbType hasPrefix:@"JAVA_DATAFLAVOR:application/x-java-remote-object;"])
262
jformats[i] = registerFormatWithPasteboard(pbType);
263
}
264
265
(*env)->ReleaseLongArrayElements(env, sDraggingFormats, jformats, JNI_COMMIT);
266
267
return TRUE;
268
}
269
270
- (BOOL)copyDraggingData:(id<NSDraggingInfo>)sender
271
{
272
DLog2(@"[CDropTarget copyDraggingData]: %@\n", self);
273
274
sPasteboardData = [[NSMutableArray alloc] init];
275
if (sPasteboardData == nil)
276
return FALSE;
277
278
// Copy all data items to a safe place since the pasteboard may go away before we'll need them:
279
NSPasteboard* pb = [sender draggingPasteboard];
280
NSUInteger i;
281
for (i = 0; i < sPasteboardItemsCount; i++) {
282
// Get a type and its data and save the data:
283
NSString* pbType = [sPasteboardTypes objectAtIndex:i];
284
// 01-10-03 Note: copying only NS-type data (until Java-specified types can make it through the AppKit)
285
// would be a good idea since we can't do anything with those CoreFoundation unknown types anyway.
286
// But I'm worried that it would break something in Fuller so I'm leaving this here as a reminder,
287
// to be evaluated later.
288
//id pbData = [pbType hasPrefix:@"NS"] ? [pb dataForType:pbType] : nil; // Copy only NS-type data!
289
id pbData = [pb dataForType:pbType];
290
291
// If the data is null we can't store it in the array - an exception would be thrown.
292
// We use the special object NSNull instead which is kosher.
293
if (pbData == nil)
294
pbData = [NSNull null];
295
296
[((NSMutableArray*) sPasteboardData) addObject:pbData];
297
}
298
299
return TRUE;
300
}
301
302
- (NSData*) getDraggingDataForURL:(NSData*)data
303
{
304
NSData* result = nil;
305
306
// Convert data into a property list if possible:
307
NSPropertyListFormat propertyListFormat;
308
NSString* errorString = nil;
309
id propertyList = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable
310
format:&propertyListFormat errorDescription:&errorString];
311
312
// URL types have only a single URL string in an array:
313
if (propertyList != nil && errorString == nil && [propertyList isKindOfClass:[NSArray class]]) {
314
NSArray* array = (NSArray*) propertyList;
315
if ([array count] > 0) {
316
NSString* url = (NSString*) [array objectAtIndex:0];
317
if (url != nil && [url length] > 0)
318
result = [url dataUsingEncoding:[url fastestEncoding]];
319
}
320
}
321
322
return result;
323
}
324
325
- (jobject) copyDraggingDataForFormat:(jlong)format
326
{
327
JNIEnv* env = [ThreadUtilities getJNIEnvUncached]; // Join the main thread by requesting uncached environment
328
329
NSData* data = nil;
330
331
// Convert the Java format (datatransferer int index) to a pasteboard format (NSString):
332
NSString* pbType = formatForIndex(format);
333
if ([sPasteboardTypes containsObject:pbType]) {
334
NSUInteger dataIndex = [sPasteboardTypes indexOfObject:pbType];
335
data = [sPasteboardData objectAtIndex:dataIndex];
336
337
if ((id) data == [NSNull null])
338
data = nil;
339
340
// format == 8 (CF_URL in CDataTransferer): we need a URL-to-String conversion:
341
else if ([pbType isEqualToString:@"Apple URL pasteboard type"])
342
data = [self getDraggingDataForURL:data];
343
}
344
345
// Get NS data:
346
char* dataBytes = (data != nil) ? (char*) [data bytes] : "Unsupported type";
347
NSUInteger dataLength = (data != nil) ? [data length] : sizeof("Unsupported type");
348
349
// Create a global byte array:
350
jbyteArray lbyteArray = (*env)->NewByteArray(env, dataLength);
351
if (lbyteArray == nil)
352
return nil;
353
jbyteArray gbyteArray = (jbyteArray) JNFNewGlobalRef(env, lbyteArray);
354
(*env)->DeleteLocalRef(env, lbyteArray);
355
if (gbyteArray == nil)
356
return nil;
357
358
// Get byte array elements:
359
jboolean isCopy;
360
jbyte* jbytes = (*env)->GetByteArrayElements(env, gbyteArray, &isCopy);
361
if (jbytes == nil)
362
return nil;
363
364
// Copy data to byte array and release elements:
365
memcpy(jbytes, dataBytes, dataLength);
366
(*env)->ReleaseByteArrayElements(env, gbyteArray, jbytes, JNI_COMMIT);
367
368
// In case of an error make sure to return nil:
369
if ((*env)->ExceptionOccurred(env)) {
370
(*env)->ExceptionDescribe(env);
371
gbyteArray = nil;
372
}
373
374
return gbyteArray;
375
}
376
377
- (void)safeReleaseDraggingData:(NSNumber *)arg
378
{
379
jlong draggingSequenceNumber = [arg longLongValue];
380
381
// Make sure dragging data is released only if no new drag is under way. If a new drag
382
// has been initiated it has released the old dragging data already. This has to be called
383
// on the native event thread - otherwise we'd need to start synchronizing.
384
if (draggingSequenceNumber == sDraggingSequenceNumber)
385
[self releaseDraggingData];
386
}
387
388
- (void)javaDraggingEnded:(jlong)draggingSequenceNumber success:(BOOL)jsuccess action:(jint)jdropaction
389
{
390
NSNumber *draggingSequenceNumberID = [NSNumber numberWithLongLong:draggingSequenceNumber];
391
// Report back actual Swing success, not what AppKit thinks
392
sDraggingError = !jsuccess;
393
sDragOperation = [DnDUtilities mapJavaDragOperationToNS:jdropaction];
394
395
// Release dragging data if any when Java's AWT event thread is all finished.
396
// Make sure dragging data is released on the native event thread.
397
[ThreadUtilities performOnMainThread:@selector(safeReleaseDraggingData:) on:self withObject:draggingSequenceNumberID waitUntilDone:NO];
398
}
399
400
- (jint)currentJavaActions {
401
return [DnDUtilities mapNSDragOperationToJava:sUpdateOperation];
402
}
403
404
/******************************** BEGIN NSDraggingDestination Interface ********************************/
405
406
407
// Private API to calculate the current Java actions
408
- (void) calculateCurrentSourceActions:(jint *)actions dropAction:(jint *)dropAction
409
{
410
// Get the raw (unmodified by keys) source actions
411
id jrsDrag = objc_lookUpClass("JRSDrag");
412
if (jrsDrag != nil) {
413
NSDragOperation rawDragActions = (NSDragOperation) [jrsDrag performSelector:@selector(currentAllowableActions)];
414
if (rawDragActions != NSDragOperationNone) {
415
// Both actions and dropAction default to the rawActions
416
*actions = [DnDUtilities mapNSDragOperationMaskToJava:rawDragActions];
417
*dropAction = *actions;
418
419
// Get the current key modifiers.
420
NSUInteger dragModifiers = (NSUInteger) [jrsDrag performSelector:@selector(currentModifiers)];
421
// Either the drop action is narrowed as per Java rules (MOVE, COPY, LINK, NONE) or by the drag modifiers
422
if (dragModifiers) {
423
// Get the user selected operation based on the drag modifiers, then return the intersection
424
NSDragOperation currentOp = [DnDUtilities nsDragOperationForModifiers:dragModifiers];
425
NSDragOperation allowedOp = rawDragActions & currentOp;
426
427
*dropAction = [DnDUtilities mapNSDragOperationToJava:allowedOp];
428
}
429
}
430
}
431
*dropAction = [DnDUtilities narrowJavaDropActions:*dropAction];
432
}
433
434
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
435
{
436
DLog2(@"[CDropTarget draggingEntered]: %@\n", self);
437
438
sCurrentDropTarget = self;
439
440
JNIEnv* env = [ThreadUtilities getJNIEnv];
441
NSInteger draggingSequenceNumber = [sender draggingSequenceNumber];
442
443
// Set the initial drag operation return value:
444
NSDragOperation dragOp = NSDragOperationNone;
445
sJavaDropOperation = java_awt_dnd_DnDConstants_ACTION_NONE;
446
447
// We could probably special-case some stuff if drag and drop objects match:
448
//if ([sender dragSource] == fView)
449
450
if (draggingSequenceNumber != sDraggingSequenceNumber) {
451
sDraggingSequenceNumber = draggingSequenceNumber;
452
sDraggingError = FALSE;
453
454
// Delete any drop target context peer left over from a previous drag:
455
if (fDropTargetContextPeer != NULL) {
456
JNFDeleteGlobalRef(env, fDropTargetContextPeer);
457
fDropTargetContextPeer = NULL;
458
}
459
460
// Look up the CDropTargetContextPeer class:
461
JNF_STATIC_MEMBER_CACHE(getDropTargetContextPeerMethod, jc_CDropTargetContextPeer, "getDropTargetContextPeer", "()Lsun/lwawt/macosx/CDropTargetContextPeer;");
462
if (sDraggingError == FALSE) {
463
// Create a new drop target context peer:
464
jobject dropTargetContextPeer = JNFCallStaticObjectMethod(env, getDropTargetContextPeerMethod);
465
466
if (dropTargetContextPeer != nil) {
467
fDropTargetContextPeer = JNFNewGlobalRef(env, dropTargetContextPeer);
468
(*env)->DeleteLocalRef(env, dropTargetContextPeer);
469
}
470
}
471
472
// Get dragging types (dragging data is only copied if dropped):
473
if (sDraggingError == FALSE && [self copyDraggingTypes:sender] == FALSE)
474
sDraggingError = TRUE;
475
}
476
477
if (sDraggingError == FALSE) {
478
sDraggingExited = FALSE;
479
sDraggingLocation = [sender draggingLocation];
480
NSPoint javaLocation = [fView convertPoint:sDraggingLocation fromView:nil];
481
javaLocation.y = fView.window.frame.size.height - javaLocation.y;
482
483
DLog5(@"+ dragEnter: loc native %f, %f, java %f, %f\n", sDraggingLocation.x, sDraggingLocation.y, javaLocation.x, javaLocation.y);
484
485
////////// BEGIN Calculate the current drag actions //////////
486
jint actions = java_awt_dnd_DnDConstants_ACTION_NONE;
487
jint dropAction = actions;
488
489
[self calculateCurrentSourceActions:&actions dropAction:&dropAction];
490
491
sJavaDropOperation = dropAction;
492
////////// END Calculate the current drag actions //////////
493
494
jlongArray formats = sDraggingFormats;
495
496
JNF_MEMBER_CACHE(handleEnterMessageMethod, jc_CDropTargetContextPeer, "handleEnterMessage", "(Ljava/awt/Component;IIII[JJ)I");
497
if (sDraggingError == FALSE) {
498
// Double-casting self gets rid of 'different size' compiler warning:
499
// AWT_THREADING Safe (CToolkitThreadBlockedHandler)
500
actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod,
501
fComponent, (jint) javaLocation.x, (jint) javaLocation.y,
502
dropAction, actions, formats, ptr_to_jlong(self));
503
}
504
505
if (sDraggingError == FALSE) {
506
// Initialize drag operation:
507
sDragOperation = NSDragOperationNone;
508
509
// Map Java actions back to NSDragOperation.
510
// 1-6-03 Note: if the entry point of this CDropTarget isn't covered by a droppable component
511
// (as can be the case with lightweight children) we must not return NSDragOperationNone
512
// since that would prevent dropping into any of the contained drop targets.
513
// Unfortunately there is no easy way to test this so we just test actions and override them
514
// with GENERIC if necessary. Proper drag operations will be returned by draggingUpdated: which is
515
// called right away, taking care of setting the right cursor and snap-back action.
516
dragOp = ((actions != java_awt_dnd_DnDConstants_ACTION_NONE) ?
517
[DnDUtilities mapJavaDragOperationToNS:dropAction] : NSDragOperationGeneric);
518
519
// Remember the dragOp for no-op'd update messages:
520
sUpdateOperation = dragOp;
521
}
522
}
523
524
// 9-11-02 Note: the native event thread would not handle an exception gracefully:
525
//if (sDraggingError == TRUE)
526
// [NSException raise:NSGenericException format:@"[CDropTarget draggingEntered] failed."];
527
528
DLog2(@"[CDropTarget draggingEntered]: returning %lu\n", (unsigned long) dragOp);
529
530
return dragOp;
531
}
532
533
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
534
{
535
//DLog2(@"[CDropTarget draggingUpdated]: %@\n", self);
536
537
sCurrentDropTarget = self;
538
539
// Set the initial drag operation return value:
540
NSDragOperation dragOp = (sDraggingError == FALSE ? sUpdateOperation : NSDragOperationNone);
541
542
// There are two things we would be interested in:
543
// a) mouse pointer has moved
544
// b) drag actions (key modifiers) have changed
545
546
NSPoint draggingLocation = [sender draggingLocation];
547
JNIEnv* env = [ThreadUtilities getJNIEnv];
548
549
BOOL notifyJava = FALSE;
550
551
// a) mouse pointer has moved:
552
if (NSEqualPoints(draggingLocation, sDraggingLocation) == FALSE) {
553
//DLog2(@"[CDropTarget draggingUpdated]: mouse moved, %@\n", self);
554
sDraggingLocation = draggingLocation;
555
notifyJava = TRUE;
556
}
557
558
// b) drag actions (key modifiers) have changed (handleMotionMessage() will do proper notifications):
559
////////// BEGIN Calculate the current drag actions //////////
560
jint actions = java_awt_dnd_DnDConstants_ACTION_NONE;
561
jint dropAction = actions;
562
563
[self calculateCurrentSourceActions:&actions dropAction:&dropAction];
564
565
if (sJavaDropOperation != dropAction) {
566
sJavaDropOperation = dropAction;
567
notifyJava = TRUE;
568
}
569
////////// END Calculate the current drag actions //////////
570
571
jint userAction = dropAction;
572
573
// Should we notify Java things have changed?
574
if (sDraggingError == FALSE && notifyJava) {
575
NSPoint javaLocation = [fView convertPoint:sDraggingLocation fromView:nil];
576
javaLocation.y = fView.window.frame.size.height - javaLocation.y;
577
//DLog5(@" : dragMoved: loc native %f, %f, java %f, %f\n", sDraggingLocation.x, sDraggingLocation.y, javaLocation.x, javaLocation.y);
578
579
jlongArray formats = sDraggingFormats;
580
581
JNF_MEMBER_CACHE(handleMotionMessageMethod, jc_CDropTargetContextPeer, "handleMotionMessage", "(Ljava/awt/Component;IIII[JJ)I");
582
if (sDraggingError == FALSE) {
583
DLog3(@" >> posting handleMotionMessage, point %f, %f", javaLocation.x, javaLocation.y);
584
userAction = JNFCallIntMethod(env, fDropTargetContextPeer, handleMotionMessageMethod, fComponent, (jint) javaLocation.x, (jint) javaLocation.y, dropAction, actions, formats, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
585
}
586
587
if (sDraggingError == FALSE) {
588
dragOp = [DnDUtilities mapJavaDragOperationToNS:userAction];
589
590
// Remember the dragOp for no-op'd update messages:
591
sUpdateOperation = dragOp;
592
} else {
593
dragOp = NSDragOperationNone;
594
}
595
}
596
597
DLog2(@"[CDropTarget draggingUpdated]: returning %lu\n", (unsigned long) dragOp);
598
599
return dragOp;
600
}
601
602
- (void)draggingExited:(id<NSDraggingInfo>)sender
603
{
604
DLog2(@"[CDropTarget draggingExited]: %@\n", self);
605
606
sCurrentDropTarget = nil;
607
608
JNIEnv* env = [ThreadUtilities getJNIEnv];
609
610
if (sDraggingExited == FALSE && sDraggingError == FALSE) {
611
JNF_MEMBER_CACHE(handleExitMessageMethod, jc_CDropTargetContextPeer, "handleExitMessage", "(Ljava/awt/Component;J)V");
612
if (sDraggingError == FALSE) {
613
DLog3(@" - dragExit: loc native %f, %f\n", sDraggingLocation.x, sDraggingLocation.y);
614
// AWT_THREADING Safe (CToolkitThreadBlockedHandler)
615
JNFCallVoidMethod(env, fDropTargetContextPeer,
616
handleExitMessageMethod, fComponent, ptr_to_jlong(self));
617
}
618
619
// 5-27-03 Note: [Radar 3270455]
620
// -draggingExited: can be called both by the AppKit and by -performDragOperation: but shouldn't execute
621
// twice per drop since cleanup code like that in swing/plaf/basic/BasicDropTargetListener would throw NPEs.
622
sDraggingExited = TRUE;
623
}
624
625
DLog(@"[CDropTarget draggingExited]: returning.\n");
626
}
627
628
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
629
{
630
DLog2(@"[CDropTarget prepareForDragOperation]: %@\n", self);
631
DLog2(@"[CDropTarget prepareForDragOperation]: returning %@\n", (sDraggingError ? @"NO" : @"YES"));
632
633
return sDraggingError ? NO : YES;
634
}
635
636
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
637
{
638
DLog2(@"[CDropTarget performDragOperation]: %@\n", self);
639
640
sCurrentDropTarget = nil;
641
642
JNIEnv* env = [ThreadUtilities getJNIEnv];
643
644
// Now copy dragging data:
645
if (sDraggingError == FALSE && [self copyDraggingData:sender] == FALSE)
646
sDraggingError = TRUE;
647
648
if (sDraggingError == FALSE) {
649
sDraggingLocation = [sender draggingLocation];
650
NSPoint javaLocation = [fView convertPoint:sDraggingLocation fromView:nil];
651
// The y coordinate that comes in the NSDraggingInfo seems to be reversed - probably
652
// has to do something with the type of view it comes to.
653
// This is the earliest place where we can correct it.
654
javaLocation.y = fView.window.frame.size.height - javaLocation.y;
655
656
jint actions = [DnDUtilities mapNSDragOperationMaskToJava:[sender draggingSourceOperationMask]];
657
jint dropAction = sJavaDropOperation;
658
659
jlongArray formats = sDraggingFormats;
660
661
JNF_MEMBER_CACHE(handleDropMessageMethod, jc_CDropTargetContextPeer, "handleDropMessage", "(Ljava/awt/Component;IIII[JJ)V");
662
663
if (sDraggingError == FALSE) {
664
JNFCallVoidMethod(env, fDropTargetContextPeer, handleDropMessageMethod, fComponent, (jint) javaLocation.x, (jint) javaLocation.y, dropAction, actions, formats, ptr_to_jlong(self)); // AWT_THREADING Safe (event)
665
}
666
667
if (sDraggingError == FALSE) {
668
JNF_MEMBER_CACHE(flushEventsMethod, jc_CDropTargetContextPeer, "flushEvents", "(Ljava/awt/Component;)V");
669
if (sDraggingError == FALSE) {
670
JNFCallVoidMethod(env, fDropTargetContextPeer, flushEventsMethod, fComponent); // AWT_THREADING Safe (AWTRunLoopMode)
671
}
672
}
673
} else {
674
// 8-19-03 Note: [Radar 3368754]
675
// draggingExited: is not called after a drop - we must do that here ... but only in case
676
// of an error, instead of drop(). Otherwise we get twice the cleanup in shared code.
677
[self draggingExited:sender];
678
}
679
680
// TODO:BG
681
// [(id)sender _setLastDragDestinationOperation:sDragOperation];
682
683
684
DLog2(@"[CDropTarget performDragOperation]: returning %@\n", (sDraggingError ? @"NO" : @"YES"));
685
686
return !sDraggingError;
687
}
688
689
- (void)concludeDragOperation:(id<NSDraggingInfo>)sender
690
{
691
sCurrentDropTarget = nil;
692
693
DLog2(@"[CDropTarget concludeDragOperation]: %@\n", self);
694
DLog(@"[CDropTarget concludeDragOperation]: returning.\n");
695
}
696
697
// 9-11-02 Note: draggingEnded is not yet implemented by the AppKit.
698
- (void)draggingEnded:(id<NSDraggingInfo>)sender
699
{
700
sCurrentDropTarget = nil;
701
702
DLog2(@"[CDropTarget draggingEnded]: %@\n", self);
703
DLog(@"[CDropTarget draggingEnded]: returning.\n");
704
}
705
706
/******************************** END NSDraggingDestination Interface ********************************/
707
708
@end
709
710
711
/*
712
* Class: sun_lwawt_macosx_CDropTarget
713
* Method: createNativeDropTarget
714
* Signature: (Ljava/awt/dnd/DropTarget;Ljava/awt/Component;Ljava/awt/peer/ComponentPeer;J)J
715
*/
716
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDropTarget_createNativeDropTarget
717
(JNIEnv *env, jobject jthis, jobject jdroptarget, jobject jcomponent, jobject jpeer, jlong jnativepeer)
718
{
719
CDropTarget* dropTarget = nil;
720
721
JNF_COCOA_ENTER(env);
722
id controlObj = (id) jlong_to_ptr(jnativepeer);
723
dropTarget = [[CDropTarget alloc] init:jdroptarget component:jcomponent peer:jpeer control:controlObj];
724
JNF_COCOA_EXIT(env);
725
726
return ptr_to_jlong(dropTarget);
727
}
728
729
/*
730
* Class: sun_lwawt_macosx_CDropTarget
731
* Method: releaseNativeDropTarget
732
* Signature: (J)V
733
*/
734
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDropTarget_releaseNativeDropTarget
735
(JNIEnv *env, jobject jthis, jlong nativeDropTargetVal)
736
{
737
id dropTarget = (id)jlong_to_ptr(nativeDropTargetVal);
738
739
JNF_COCOA_ENTER(env);
740
[dropTarget removeFromView:env];
741
JNF_COCOA_EXIT(env);
742
}
743
744