4632N/A/*
4632N/A * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
4632N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4632N/A *
4632N/A * This code is free software; you can redistribute it and/or modify it
4632N/A * under the terms of the GNU General Public License version 2 only, as
4632N/A * published by the Free Software Foundation. Oracle designates this
4632N/A * particular file as subject to the "Classpath" exception as provided
4632N/A * by Oracle in the LICENSE file that accompanied this code.
4632N/A *
4632N/A * This code is distributed in the hope that it will be useful, but WITHOUT
4632N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4632N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4632N/A * version 2 for more details (a copy is included in the LICENSE file that
4632N/A * accompanied this code).
4632N/A *
4632N/A * You should have received a copy of the GNU General Public License version
4632N/A * 2 along with this work; if not, write to the Free Software Foundation,
4632N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4632N/A *
4632N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4632N/A * or visit www.oracle.com if you need additional information or have any
4632N/A * questions.
4632N/A */
4632N/A
4632N/A
4632N/A/*
4632N/ADocumentation for Drag and Drop (Radar 3065640)
4632N/AThere are several problems with Drag and Drop - notably, the mismatch between Java, Cocoa, and Carbon
4632N/A
4632N/A Java reports both the original source actions, and the user-selected actions (selected using KB modifiers) to both the source and target during the drag. AppKit only reports to the destination during the drag. This was solved by directly asking CGS for the KB state during the source's image moved callback.
4632N/A
4632N/A Java uses Shift/Move, Control/Copy and Shift+Control/Link. AppKit uses Command/Move, Alternate/Copy and Control/Link. Carbon uses Command/Move, Alternate/Copy and Command+Alternate/Link. This is bad, because Control overlaps between Java and AppKit. In this case, we choose compatibility between Carbon and Java (Java wins over AppKit wrt Control). This means that drags between Java applications will work correctly, regardless of whether you use the Carbon or the Java key modifiers. Drags to Java applications will work correctly regardless of whether you use the Carbon or the Java key modifiers. Drags from Java applications to non-Java applications will only work if you use the Carbon modifiers.
4632N/A
4632N/A The reason we can't just set the CoreDrag(G/S)etAllowableActions directly (while ignoring the modifier keys) is because Carbon apps traditionally don't pay any attention - they only look at the modifier keys.
4632N/A */
4632N/A
4632N/A#import <Cocoa/Cocoa.h>
4632N/A#import "DnDUtilities.h"
4632N/A#import "java_awt_dnd_DnDConstants.h"
4632N/A#import "java_awt_event_InputEvent.h"
4632N/A
4632N/A@implementation DnDUtilities
4632N/A
4632N/A// Make sure we don't let other apps see local drags by using a process unique pasteboard type.
4632N/A// This may not work in the Applet case, since they are all running in the same VM
4632N/A+ (NSString *) javaPboardType {
4632N/A static NSString *customJavaPboardType = nil;
4632N/A if (customJavaPboardType == nil)
4632N/A customJavaPboardType = [[NSString stringWithFormat:@"NSJavaPboardType-%@", [[NSProcessInfo processInfo] globallyUniqueString]] retain];
4632N/A return customJavaPboardType;
4632N/A}
4632N/A
4632N/A+ (jint)mapNSDragOperationToJava:(NSDragOperation)dragOperation
4632N/A{
4632N/A jint result = java_awt_dnd_DnDConstants_ACTION_NONE;
4632N/A
4632N/A if ((dragOperation & NSDragOperationCopy) != 0) // 1
4632N/A result = ((dragOperation & NSDragOperationMove) == 0) ? java_awt_dnd_DnDConstants_ACTION_COPY : java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE;
4632N/A
4632N/A else if ((dragOperation & NSDragOperationMove) != 0) // 16
4632N/A result = java_awt_dnd_DnDConstants_ACTION_MOVE;
4632N/A
4632N/A else if ((dragOperation & NSDragOperationLink) != 0) // 2
4632N/A result = java_awt_dnd_DnDConstants_ACTION_LINK;
4632N/A
4632N/A else if ((dragOperation & NSDragOperationGeneric) != 0) // 4
4632N/A result = java_awt_dnd_DnDConstants_ACTION_MOVE;
4632N/A
4632N/A // Pre-empted by the above cases:
4632N/A //else if (dragOperation == NSDragOperationEvery) // UINT_MAX
4632N/A // result = java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE;
4632N/A
4632N/A // To be rejected:
4632N/A //else if ((dragOperation & NSDragOperationPrivate) != 0) // 8
4632N/A //else if ((dragOperation & NSDragOperationAll_Obsolete) != 0) // 15
4632N/A //else if ((dragOperation & NSDragOperationDelete) != 0) // 32
4632N/A
4632N/A return result;
4632N/A}
4632N/A
4632N/A+ (jint)mapNSDragOperationMaskToJava:(NSDragOperation)dragOperation
4632N/A{
4632N/A jint result = java_awt_dnd_DnDConstants_ACTION_NONE;
4632N/A
4632N/A if (dragOperation & NSDragOperationMove)
4632N/A result |= java_awt_dnd_DnDConstants_ACTION_MOVE;
4632N/A
4632N/A if (dragOperation & NSDragOperationCopy)
4632N/A result |= java_awt_dnd_DnDConstants_ACTION_COPY;
4632N/A
4632N/A if (dragOperation & NSDragOperationLink)
4632N/A result |= java_awt_dnd_DnDConstants_ACTION_LINK;
4632N/A
4632N/A // Only look at Generic if none of the other options are specified
4632N/A if ( (dragOperation & NSDragOperationGeneric) && !(dragOperation & (NSDragOperationMove|NSDragOperationCopy|NSDragOperationLink)) )
4632N/A result |= java_awt_dnd_DnDConstants_ACTION_MOVE;
4632N/A
4632N/A return result;
4632N/A}
4632N/A
4632N/A+ (jint)narrowJavaDropActions:(jint)actions
4632N/A{
4632N/A if (YES) {
4632N/A // Order is defined in the java.awt.dnd.DropTargetDropEvent JavaDoc
4632N/A if (actions & java_awt_dnd_DnDConstants_ACTION_MOVE) {
4632N/A return java_awt_dnd_DnDConstants_ACTION_MOVE;
4632N/A }
4632N/A if (actions & java_awt_dnd_DnDConstants_ACTION_COPY) {
4632N/A return java_awt_dnd_DnDConstants_ACTION_COPY;
4632N/A }
4632N/A if (actions & java_awt_dnd_DnDConstants_ACTION_LINK) {
4632N/A return java_awt_dnd_DnDConstants_ACTION_LINK;
4632N/A }
4632N/A } else {
4632N/A // Order is what is most intuitive on Mac OS X
4632N/A if (actions & java_awt_dnd_DnDConstants_ACTION_COPY) {
4632N/A return java_awt_dnd_DnDConstants_ACTION_COPY;
4632N/A }
4632N/A if (actions & java_awt_dnd_DnDConstants_ACTION_LINK) {
4632N/A return java_awt_dnd_DnDConstants_ACTION_LINK;
4632N/A }
4632N/A if (actions & java_awt_dnd_DnDConstants_ACTION_MOVE) {
4632N/A return java_awt_dnd_DnDConstants_ACTION_MOVE;
4632N/A }
4632N/A }
4632N/A
4632N/A return java_awt_dnd_DnDConstants_ACTION_NONE;
4632N/A}
4632N/A
4632N/A+ (NSDragOperation)mapJavaDragOperationToNS:(jint)dragOperation
4632N/A{
4632N/A NSDragOperation result = NSDragOperationNone;
4632N/A
4632N/A switch (dragOperation) {
4632N/A case java_awt_dnd_DnDConstants_ACTION_NONE: // 0
4632N/A result = NSDragOperationNone;
4632N/A break;
4632N/A case java_awt_dnd_DnDConstants_ACTION_COPY: // 1
4632N/A result = NSDragOperationCopy;
4632N/A break;
4632N/A case java_awt_dnd_DnDConstants_ACTION_MOVE: // 2
4632N/A result = NSDragOperationMove;
4632N/A break;
4632N/A case java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE: // 3
4632N/A result = NSDragOperationCopy | NSDragOperationMove;
4632N/A break;
4632N/A case java_awt_dnd_DnDConstants_ACTION_LINK: // 1073741824L
4632N/A result = NSDragOperationLink;
4632N/A break;
4632N/A case (java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE | java_awt_dnd_DnDConstants_ACTION_LINK):
4632N/A result = NSDragOperationCopy | NSDragOperationMove | NSDragOperationLink;
4632N/A break;
4632N/A }
4632N/A
4632N/A if (result != NSDragOperationNone) {
4632N/A result |= NSDragOperationGeneric;
4632N/A }
4632N/A
4632N/A return result;
4632N/A}
4632N/A
4632N/A// Mouse and key modifiers mapping:
4632N/A+ (NSUInteger)mapJavaExtModifiersToNSMouseDownButtons:(jint)modifiers
4632N/A{
4632N/A NSUInteger result = NSLeftMouseDown;
4632N/A
4632N/A if ((modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) != 0)
4632N/A result = NSLeftMouseDown;
4632N/A
4632N/A if ((modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) != 0)
4632N/A result = NSOtherMouseDown;
4632N/A
4632N/A if ((modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) != 0)
4632N/A result = NSRightMouseDown;
4632N/A
4632N/A return result;
4632N/A}
4632N/A
4632N/A+ (NSUInteger)mapJavaExtModifiersToNSMouseUpButtons:(jint)modifiers
4632N/A{
4632N/A NSUInteger result = NSLeftMouseUp;
4632N/A
4632N/A if ((modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) != 0)
4632N/A result = NSLeftMouseUp;
4632N/A
4632N/A if ((modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) != 0)
4632N/A result = NSOtherMouseUp;
4632N/A
4632N/A if ((modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) != 0)
4632N/A result = NSRightMouseUp;
4632N/A
4632N/A return result;
4632N/A}
4632N/A
4632N/A
4632N/A// Specialized key modifiers mappings (for DragSource.operationChanged)
4632N/A
4632N/A// Returns just the key modifiers from a java modifier flag
4632N/A+ (jint)extractJavaExtKeyModifiersFromJavaExtModifiers:(jint)modifiers
4632N/A{
4632N/A // Build the mask
4632N/A static jint mask = java_awt_event_InputEvent_SHIFT_DOWN_MASK | java_awt_event_InputEvent_CTRL_DOWN_MASK | java_awt_event_InputEvent_META_DOWN_MASK | java_awt_event_InputEvent_ALT_DOWN_MASK;
4632N/A //static int mask = java_awt_event_InputEvent_SHIFT_DOWN_MASK | java_awt_event_InputEvent_CTRL_DOWN_MASK;
4632N/A
4632N/A // Get results
4632N/A jint result = modifiers & mask;
4632N/A
4632N/A // Java appears to have 2 ALT buttons - combine them.
4632N/A if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK)
4632N/A result |= java_awt_event_InputEvent_ALT_DOWN_MASK;
4632N/A
4632N/A return result;
4632N/A}
4632N/A
4632N/A// Returns just the mouse modifiers from a java modifier flag
4632N/A+ (jint)extractJavaExtMouseModifiersFromJavaExtModifiers:(jint)modifiers
4632N/A{
4632N/A // Build the mask
4632N/A static jint mask = java_awt_event_InputEvent_BUTTON1_DOWN_MASK | java_awt_event_InputEvent_BUTTON2_DOWN_MASK | java_awt_event_InputEvent_BUTTON3_DOWN_MASK;
4632N/A
4632N/A // Get results
4632N/A return modifiers & mask;
4632N/A}
4632N/A
4632N/A+ (NSDragOperation) nsDragOperationForModifiers:(NSUInteger)modifiers {
4632N/A
4632N/A // Java first
4632N/A if ( (modifiers & NSShiftKeyMask) && (modifiers & NSControlKeyMask) ) {
4632N/A return NSDragOperationLink;
4632N/A }
4632N/A if (modifiers & NSShiftKeyMask) {
4632N/A return NSDragOperationMove;
4632N/A }
4632N/A if (modifiers & NSControlKeyMask) {
4632N/A return NSDragOperationCopy;
4632N/A }
4632N/A
4632N/A // Then native
4632N/A if ( (modifiers & NSCommandKeyMask) && (modifiers & NSAlternateKeyMask) ) {
4632N/A return NSDragOperationLink;
4632N/A }
4632N/A if (modifiers & NSCommandKeyMask) {
4632N/A return NSDragOperationMove;
4632N/A }
4632N/A if (modifiers & NSAlternateKeyMask) {
4632N/A return NSDragOperationCopy;
4632N/A }
4632N/A
4632N/A // Otherwise, we allow anything
4632N/A return NSDragOperationEvery;
4632N/A}
4632N/A
4632N/A+ (jint) javaKeyModifiersForNSDragOperation:(NSDragOperation)dragOperation {
4632N/A if (dragOperation & NSDragOperationMove)
4632N/A return java_awt_event_InputEvent_SHIFT_DOWN_MASK;
4632N/A
4632N/A if (dragOperation & NSDragOperationCopy)
4632N/A return java_awt_event_InputEvent_CTRL_DOWN_MASK;
4632N/A
4632N/A if (dragOperation & NSDragOperationLink) {
4632N/A return java_awt_event_InputEvent_SHIFT_DOWN_MASK | java_awt_event_InputEvent_CTRL_DOWN_MASK;
4632N/A }
4632N/A return 0;
4632N/A}
4632N/A
4632N/A@end