Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/awt/DnDUtilities.m
41152 views
/*1* Copyright (c) 2011, 2012, 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*/242526/*27Documentation for Drag and Drop (Radar 3065640)28There are several problems with Drag and Drop - notably, the mismatch between Java, Cocoa, and Carbon2930Java 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.3132Java 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.3334The 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.35*/3637#import <Cocoa/Cocoa.h>38#import "DnDUtilities.h"39#import "java_awt_dnd_DnDConstants.h"40#import "java_awt_event_InputEvent.h"4142@implementation DnDUtilities4344// Make sure we don't let other apps see local drags by using a process unique pasteboard type.45// This may not work in the Applet case, since they are all running in the same VM46+ (NSString *) javaPboardType {47static NSString *customJavaPboardType = nil;48if (customJavaPboardType == nil)49customJavaPboardType = [[NSString stringWithFormat:@"NSJavaPboardType-%@", [[NSProcessInfo processInfo] globallyUniqueString]] retain];50return customJavaPboardType;51}5253+ (jint)mapNSDragOperationToJava:(NSDragOperation)dragOperation54{55jint result = java_awt_dnd_DnDConstants_ACTION_NONE;5657if ((dragOperation & NSDragOperationCopy) != 0) // 158result = ((dragOperation & NSDragOperationMove) == 0) ? java_awt_dnd_DnDConstants_ACTION_COPY : java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE;5960else if ((dragOperation & NSDragOperationMove) != 0) // 1661result = java_awt_dnd_DnDConstants_ACTION_MOVE;6263else if ((dragOperation & NSDragOperationLink) != 0) // 264result = java_awt_dnd_DnDConstants_ACTION_LINK;6566else if ((dragOperation & NSDragOperationGeneric) != 0) // 467result = java_awt_dnd_DnDConstants_ACTION_MOVE;6869// Pre-empted by the above cases:70//else if (dragOperation == NSDragOperationEvery) // UINT_MAX71// result = java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE;7273// To be rejected:74//else if ((dragOperation & NSDragOperationPrivate) != 0) // 875//else if ((dragOperation & NSDragOperationAll_Obsolete) != 0) // 1576//else if ((dragOperation & NSDragOperationDelete) != 0) // 327778return result;79}8081+ (jint)mapNSDragOperationMaskToJava:(NSDragOperation)dragOperation82{83jint result = java_awt_dnd_DnDConstants_ACTION_NONE;8485if (dragOperation & NSDragOperationMove)86result |= java_awt_dnd_DnDConstants_ACTION_MOVE;8788if (dragOperation & NSDragOperationCopy)89result |= java_awt_dnd_DnDConstants_ACTION_COPY;9091if (dragOperation & NSDragOperationLink)92result |= java_awt_dnd_DnDConstants_ACTION_LINK;9394// Only look at Generic if none of the other options are specified95if ( (dragOperation & NSDragOperationGeneric) && !(dragOperation & (NSDragOperationMove|NSDragOperationCopy|NSDragOperationLink)) )96result |= java_awt_dnd_DnDConstants_ACTION_MOVE;9798return result;99}100101+ (jint)narrowJavaDropActions:(jint)actions102{103if (YES) {104// Order is defined in the java.awt.dnd.DropTargetDropEvent JavaDoc105if (actions & java_awt_dnd_DnDConstants_ACTION_MOVE) {106return java_awt_dnd_DnDConstants_ACTION_MOVE;107}108if (actions & java_awt_dnd_DnDConstants_ACTION_COPY) {109return java_awt_dnd_DnDConstants_ACTION_COPY;110}111if (actions & java_awt_dnd_DnDConstants_ACTION_LINK) {112return java_awt_dnd_DnDConstants_ACTION_LINK;113}114} else {115// Order is what is most intuitive on Mac OS X116if (actions & java_awt_dnd_DnDConstants_ACTION_COPY) {117return java_awt_dnd_DnDConstants_ACTION_COPY;118}119if (actions & java_awt_dnd_DnDConstants_ACTION_LINK) {120return java_awt_dnd_DnDConstants_ACTION_LINK;121}122if (actions & java_awt_dnd_DnDConstants_ACTION_MOVE) {123return java_awt_dnd_DnDConstants_ACTION_MOVE;124}125}126127return java_awt_dnd_DnDConstants_ACTION_NONE;128}129130+ (NSDragOperation)mapJavaDragOperationToNS:(jint)dragOperation131{132NSDragOperation result = NSDragOperationNone;133134switch (dragOperation) {135case java_awt_dnd_DnDConstants_ACTION_NONE: // 0136result = NSDragOperationNone;137break;138case java_awt_dnd_DnDConstants_ACTION_COPY: // 1139result = NSDragOperationCopy;140break;141case java_awt_dnd_DnDConstants_ACTION_MOVE: // 2142result = NSDragOperationMove;143break;144case java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE: // 3145result = NSDragOperationCopy | NSDragOperationMove;146break;147case java_awt_dnd_DnDConstants_ACTION_LINK: // 1073741824L148result = NSDragOperationLink;149break;150case (java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE | java_awt_dnd_DnDConstants_ACTION_LINK):151result = NSDragOperationCopy | NSDragOperationMove | NSDragOperationLink;152break;153}154155if (result != NSDragOperationNone) {156result |= NSDragOperationGeneric;157}158159return result;160}161162// Mouse and key modifiers mapping:163+ (NSUInteger)mapJavaExtModifiersToNSMouseDownButtons:(jint)modifiers164{165NSUInteger result = NSLeftMouseDown;166167if ((modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) != 0)168result = NSLeftMouseDown;169170if ((modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) != 0)171result = NSOtherMouseDown;172173if ((modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) != 0)174result = NSRightMouseDown;175176return result;177}178179+ (NSUInteger)mapJavaExtModifiersToNSMouseUpButtons:(jint)modifiers180{181NSUInteger result = NSLeftMouseUp;182183if ((modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) != 0)184result = NSLeftMouseUp;185186if ((modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) != 0)187result = NSOtherMouseUp;188189if ((modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) != 0)190result = NSRightMouseUp;191192return result;193}194195196// Specialized key modifiers mappings (for DragSource.operationChanged)197198// Returns just the key modifiers from a java modifier flag199+ (jint)extractJavaExtKeyModifiersFromJavaExtModifiers:(jint)modifiers200{201// Build the mask202static 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;203//static int mask = java_awt_event_InputEvent_SHIFT_DOWN_MASK | java_awt_event_InputEvent_CTRL_DOWN_MASK;204205// Get results206jint result = modifiers & mask;207208// Java appears to have 2 ALT buttons - combine them.209if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK)210result |= java_awt_event_InputEvent_ALT_DOWN_MASK;211212return result;213}214215// Returns just the mouse modifiers from a java modifier flag216+ (jint)extractJavaExtMouseModifiersFromJavaExtModifiers:(jint)modifiers217{218// Build the mask219static jint mask = java_awt_event_InputEvent_BUTTON1_DOWN_MASK | java_awt_event_InputEvent_BUTTON2_DOWN_MASK | java_awt_event_InputEvent_BUTTON3_DOWN_MASK;220221// Get results222return modifiers & mask;223}224225+ (NSDragOperation) nsDragOperationForModifiers:(NSUInteger)modifiers {226227// Java first228if ( (modifiers & NSShiftKeyMask) && (modifiers & NSControlKeyMask) ) {229return NSDragOperationLink;230}231if (modifiers & NSShiftKeyMask) {232return NSDragOperationMove;233}234if (modifiers & NSControlKeyMask) {235return NSDragOperationCopy;236}237238// Then native239if ( (modifiers & NSCommandKeyMask) && (modifiers & NSAlternateKeyMask) ) {240return NSDragOperationLink;241}242if (modifiers & NSCommandKeyMask) {243return NSDragOperationMove;244}245if (modifiers & NSAlternateKeyMask) {246return NSDragOperationCopy;247}248249// Otherwise, we allow anything250return NSDragOperationEvery;251}252253+ (jint) javaKeyModifiersForNSDragOperation:(NSDragOperation)dragOperation {254if (dragOperation & NSDragOperationMove)255return java_awt_event_InputEvent_SHIFT_DOWN_MASK;256257if (dragOperation & NSDragOperationCopy)258return java_awt_event_InputEvent_CTRL_DOWN_MASK;259260if (dragOperation & NSDragOperationLink) {261return java_awt_event_InputEvent_SHIFT_DOWN_MASK | java_awt_event_InputEvent_CTRL_DOWN_MASK;262}263return 0;264}265266@end267268269