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