jdk/src/macosx/native/sun/awt/DnDUtilities.m
changeset 12047 320a714614e9
child 13781 bf3d53b1fba7
equal deleted inserted replaced
12046:378aa3362868 12047:320a714614e9
       
     1 /*
       
     2  * Copyright (c) 2011, 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 
       
    27 /*
       
    28 Documentation for Drag and Drop (Radar 3065640)
       
    29 There are several problems with Drag and Drop - notably, the mismatch between Java, Cocoa, and Carbon
       
    30 
       
    31  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.
       
    32 
       
    33  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.
       
    34 
       
    35  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.
       
    36  */
       
    37 
       
    38 #import <Cocoa/Cocoa.h>
       
    39 #import "DnDUtilities.h"
       
    40 #import "java_awt_dnd_DnDConstants.h"
       
    41 #import "java_awt_event_InputEvent.h"
       
    42 
       
    43 @implementation DnDUtilities
       
    44 
       
    45 // Make sure we don't let other apps see local drags by using a process unique pasteboard type.
       
    46 // This may not work in the Applet case, since they are all running in the same VM
       
    47 + (NSString *) javaPboardType {
       
    48     static NSString *customJavaPboardType = nil;
       
    49     if (customJavaPboardType == nil)
       
    50         customJavaPboardType = [[NSString stringWithFormat:@"NSJavaPboardType-%@", [[NSProcessInfo processInfo] globallyUniqueString]] retain];
       
    51     return customJavaPboardType;
       
    52 }
       
    53 
       
    54 + (jint)mapNSDragOperationToJava:(NSDragOperation)dragOperation
       
    55 {
       
    56     jint result = java_awt_dnd_DnDConstants_ACTION_NONE;
       
    57 
       
    58     if ((dragOperation & NSDragOperationCopy) != 0)                    // 1
       
    59         result = ((dragOperation & NSDragOperationMove) == 0) ? java_awt_dnd_DnDConstants_ACTION_COPY : java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE;
       
    60 
       
    61     else if ((dragOperation & NSDragOperationMove) != 0)            // 16
       
    62         result = java_awt_dnd_DnDConstants_ACTION_MOVE;
       
    63 
       
    64     else if ((dragOperation & NSDragOperationLink) != 0)            // 2
       
    65         result = java_awt_dnd_DnDConstants_ACTION_LINK;
       
    66 
       
    67     else if ((dragOperation & NSDragOperationGeneric) != 0)            // 4
       
    68         result = java_awt_dnd_DnDConstants_ACTION_MOVE;
       
    69 
       
    70     // Pre-empted by the above cases:
       
    71     //else if (dragOperation == NSDragOperationEvery)                    // UINT_MAX
       
    72     //    result = java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE;
       
    73 
       
    74     // To be rejected:
       
    75     //else if ((dragOperation & NSDragOperationPrivate) != 0)        // 8
       
    76     //else if ((dragOperation & NSDragOperationAll_Obsolete) != 0)    // 15
       
    77     //else if ((dragOperation & NSDragOperationDelete) != 0)        // 32
       
    78 
       
    79     return result;
       
    80 }
       
    81 
       
    82 + (jint)mapNSDragOperationMaskToJava:(NSDragOperation)dragOperation
       
    83 {
       
    84     jint result = java_awt_dnd_DnDConstants_ACTION_NONE;
       
    85 
       
    86     if (dragOperation & NSDragOperationMove)
       
    87         result |= java_awt_dnd_DnDConstants_ACTION_MOVE;
       
    88 
       
    89     if (dragOperation & NSDragOperationCopy)
       
    90         result |= java_awt_dnd_DnDConstants_ACTION_COPY;
       
    91 
       
    92     if (dragOperation & NSDragOperationLink)
       
    93         result |= java_awt_dnd_DnDConstants_ACTION_LINK;
       
    94 
       
    95     // Only look at Generic if none of the other options are specified
       
    96     if ( (dragOperation & NSDragOperationGeneric) && !(dragOperation & (NSDragOperationMove|NSDragOperationCopy|NSDragOperationLink)) )
       
    97         result |= java_awt_dnd_DnDConstants_ACTION_MOVE;
       
    98 
       
    99     return result;
       
   100 }
       
   101 
       
   102 + (jint)narrowJavaDropActions:(jint)actions
       
   103 {
       
   104     if (YES) {
       
   105         // Order is defined in the java.awt.dnd.DropTargetDropEvent JavaDoc
       
   106         if (actions & java_awt_dnd_DnDConstants_ACTION_MOVE) {
       
   107             return java_awt_dnd_DnDConstants_ACTION_MOVE;
       
   108         }
       
   109         if (actions & java_awt_dnd_DnDConstants_ACTION_COPY) {
       
   110             return java_awt_dnd_DnDConstants_ACTION_COPY;
       
   111         }
       
   112         if (actions & java_awt_dnd_DnDConstants_ACTION_LINK) {
       
   113             return java_awt_dnd_DnDConstants_ACTION_LINK;
       
   114         }
       
   115     } else {
       
   116         // Order is what is most intuitive on Mac OS X
       
   117         if (actions & java_awt_dnd_DnDConstants_ACTION_COPY) {
       
   118             return java_awt_dnd_DnDConstants_ACTION_COPY;
       
   119         }
       
   120         if (actions & java_awt_dnd_DnDConstants_ACTION_LINK) {
       
   121             return java_awt_dnd_DnDConstants_ACTION_LINK;
       
   122         }
       
   123         if (actions & java_awt_dnd_DnDConstants_ACTION_MOVE) {
       
   124             return java_awt_dnd_DnDConstants_ACTION_MOVE;
       
   125         }
       
   126     }
       
   127 
       
   128     return java_awt_dnd_DnDConstants_ACTION_NONE;
       
   129 }
       
   130 
       
   131 + (NSDragOperation)mapJavaDragOperationToNS:(jint)dragOperation
       
   132 {
       
   133     NSDragOperation result = NSDragOperationNone;
       
   134 
       
   135     switch (dragOperation) {
       
   136         case java_awt_dnd_DnDConstants_ACTION_NONE:            // 0
       
   137             result = NSDragOperationNone;
       
   138             break;
       
   139         case java_awt_dnd_DnDConstants_ACTION_COPY:            // 1
       
   140             result = NSDragOperationCopy;
       
   141             break;
       
   142         case java_awt_dnd_DnDConstants_ACTION_MOVE:            // 2
       
   143             result = NSDragOperationMove;
       
   144             break;
       
   145         case java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE:    // 3
       
   146             result = NSDragOperationCopy | NSDragOperationMove;
       
   147             break;
       
   148         case java_awt_dnd_DnDConstants_ACTION_LINK:            // 1073741824L
       
   149             result = NSDragOperationLink;
       
   150             break;
       
   151         case (java_awt_dnd_DnDConstants_ACTION_COPY_OR_MOVE | java_awt_dnd_DnDConstants_ACTION_LINK):
       
   152             result = NSDragOperationCopy | NSDragOperationMove | NSDragOperationLink;
       
   153             break;
       
   154     }
       
   155 
       
   156         if (result != NSDragOperationNone) {
       
   157             result |= NSDragOperationGeneric;
       
   158         }
       
   159 
       
   160     return result;
       
   161 }
       
   162 
       
   163 // Mouse and key modifiers mapping:
       
   164 + (NSUInteger)mapJavaExtModifiersToNSKeyModifiers:(jint)modifiers
       
   165 {
       
   166     NSUInteger result = 0;
       
   167 
       
   168     if ((modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) != 0)
       
   169         result |= NSShiftKeyMask;
       
   170 
       
   171     if ((modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) != 0)
       
   172         result |= NSControlKeyMask;
       
   173 
       
   174     if ((modifiers & java_awt_event_InputEvent_META_DOWN_MASK) != 0)
       
   175         result |= NSCommandKeyMask;
       
   176 
       
   177     if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0)
       
   178         result |= NSAlternateKeyMask;
       
   179 
       
   180     if ((modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK) != 0)
       
   181         result |= NSAlternateKeyMask;
       
   182 
       
   183     return result;
       
   184 }
       
   185 
       
   186 + (NSUInteger)mapJavaExtModifiersToNSMouseDownButtons:(jint)modifiers
       
   187 {
       
   188     NSUInteger result = NSLeftMouseDown;
       
   189 
       
   190     if ((modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) != 0)
       
   191         result = NSLeftMouseDown;
       
   192 
       
   193     if ((modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) != 0)
       
   194         result = NSOtherMouseDown;
       
   195 
       
   196     if ((modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) != 0)
       
   197         result = NSRightMouseDown;
       
   198 
       
   199     return result;
       
   200 }
       
   201 
       
   202 + (NSUInteger)mapJavaExtModifiersToNSMouseUpButtons:(jint)modifiers
       
   203 {
       
   204     NSUInteger result = NSLeftMouseUp;
       
   205 
       
   206     if ((modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) != 0)
       
   207         result = NSLeftMouseUp;
       
   208 
       
   209     if ((modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) != 0)
       
   210         result = NSOtherMouseUp;
       
   211 
       
   212     if ((modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) != 0)
       
   213         result = NSRightMouseUp;
       
   214 
       
   215     return result;
       
   216 }
       
   217 
       
   218 
       
   219 // Specialized key modifiers mappings (for DragSource.operationChanged)
       
   220 
       
   221 // Returns just the key modifiers from a java modifier flag
       
   222 + (jint)extractJavaExtKeyModifiersFromJavaExtModifiers:(jint)modifiers
       
   223 {
       
   224     // Build the mask
       
   225     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;
       
   226     //static int mask = java_awt_event_InputEvent_SHIFT_DOWN_MASK | java_awt_event_InputEvent_CTRL_DOWN_MASK;
       
   227 
       
   228     // Get results
       
   229     jint result = modifiers & mask;
       
   230 
       
   231     // Java appears to have 2 ALT buttons - combine them.
       
   232     if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK)
       
   233         result |= java_awt_event_InputEvent_ALT_DOWN_MASK;
       
   234 
       
   235     return result;
       
   236 }
       
   237 
       
   238 // Returns just the mouse modifiers from a java modifier flag
       
   239 + (jint)extractJavaExtMouseModifiersFromJavaExtModifiers:(jint)modifiers
       
   240 {
       
   241     // Build the mask
       
   242     static jint mask = java_awt_event_InputEvent_BUTTON1_DOWN_MASK | java_awt_event_InputEvent_BUTTON2_DOWN_MASK | java_awt_event_InputEvent_BUTTON3_DOWN_MASK;
       
   243 
       
   244     // Get results
       
   245     return modifiers & mask;
       
   246 }
       
   247 
       
   248 
       
   249 + (jint)currentJavaExtKeyModifiers
       
   250 {
       
   251     NSUInteger modifiers = [NSEvent modifierFlags];
       
   252     jint jmodifiers = 0;
       
   253 
       
   254     if(modifiers & NSShiftKeyMask) {
       
   255         jmodifiers |= java_awt_event_InputEvent_SHIFT_DOWN_MASK;
       
   256     }
       
   257 
       
   258     if(modifiers & NSControlKeyMask) {
       
   259         jmodifiers |= java_awt_event_InputEvent_CTRL_DOWN_MASK;
       
   260     }
       
   261 
       
   262     if(modifiers & NSAlternateKeyMask) {
       
   263         jmodifiers |= java_awt_event_InputEvent_ALT_DOWN_MASK;
       
   264     }
       
   265 
       
   266     if(modifiers & NSCommandKeyMask) {
       
   267         jmodifiers |= java_awt_event_InputEvent_META_DOWN_MASK;
       
   268     }
       
   269 
       
   270     return jmodifiers;
       
   271 }
       
   272 
       
   273 
       
   274 + (NSDragOperation) nsDragOperationForModifiers:(NSUInteger)modifiers {
       
   275 
       
   276     // Java first
       
   277     if ( (modifiers & NSShiftKeyMask) && (modifiers & NSControlKeyMask) ) {
       
   278         return NSDragOperationLink;
       
   279     }
       
   280     if (modifiers & NSShiftKeyMask) {
       
   281         return NSDragOperationMove;
       
   282     }
       
   283     if (modifiers & NSControlKeyMask) {
       
   284         return NSDragOperationCopy;
       
   285     }
       
   286 
       
   287     // Then native
       
   288     if ( (modifiers & NSCommandKeyMask) && (modifiers & NSAlternateKeyMask) ) {
       
   289         return NSDragOperationLink;
       
   290     }
       
   291     if (modifiers & NSCommandKeyMask) {
       
   292         return NSDragOperationMove;
       
   293     }
       
   294     if (modifiers & NSAlternateKeyMask) {
       
   295         return NSDragOperationCopy;
       
   296     }
       
   297 
       
   298     // Otherwise, we allow anything
       
   299     return NSDragOperationEvery;
       
   300 }
       
   301 
       
   302 + (jint) javaKeyModifiersForNSDragOperation:(NSDragOperation)dragOperation {
       
   303     if (dragOperation & NSDragOperationMove)
       
   304         return java_awt_event_InputEvent_SHIFT_DOWN_MASK;
       
   305 
       
   306     if (dragOperation & NSDragOperationCopy)
       
   307         return java_awt_event_InputEvent_CTRL_DOWN_MASK;
       
   308 
       
   309     if (dragOperation & NSDragOperationLink) {
       
   310         return java_awt_event_InputEvent_SHIFT_DOWN_MASK | java_awt_event_InputEvent_CTRL_DOWN_MASK;
       
   311     }
       
   312     return 0;
       
   313 }
       
   314 
       
   315 @end