1 /*
   2  * Copyright (c) 1997, 2009, 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 package sun.awt.windows;
  27 
  28 import java.awt.Component;
  29 import java.awt.Cursor;
  30 import java.awt.Image;
  31 import java.awt.Point;
  32 import java.awt.image.BufferedImage;
  33 import java.awt.image.DataBufferInt;
  34 
  35 import java.awt.datatransfer.Transferable;
  36 
  37 import java.awt.dnd.DragGestureEvent;
  38 import java.awt.dnd.InvalidDnDOperationException;
  39 
  40 import java.awt.event.InputEvent;
  41 
  42 import java.util.Map;
  43 
  44 import sun.awt.dnd.SunDragSourceContextPeer;
  45 
  46 /**
  47  * <p>
  48  * TBC
  49  * </p>
  50  *
  51  * @since JDK1.2
  52  *
  53  */
  54 
  55 final class WDragSourceContextPeer extends SunDragSourceContextPeer {
  56     public void startSecondaryEventLoop(){
  57         WToolkit.startSecondaryEventLoop();
  58     }
  59     public void quitSecondaryEventLoop(){
  60         WToolkit.quitSecondaryEventLoop();
  61     }
  62 
  63     private static final WDragSourceContextPeer theInstance =
  64         new WDragSourceContextPeer(null);
  65 
  66     /**
  67      * construct a new WDragSourceContextPeer. package private
  68      */
  69 
  70     private WDragSourceContextPeer(DragGestureEvent dge) {
  71         super(dge);
  72     }
  73 
  74     static WDragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
  75         theInstance.setTrigger(dge);
  76         return theInstance;
  77     }
  78 
  79     protected void startDrag(Transferable trans,
  80                              long[] formats, Map formatMap) {
  81 
  82         long nativeCtxtLocal = 0;
  83 
  84         nativeCtxtLocal = createDragSource(getTrigger().getComponent(),
  85                                            trans,
  86                                            getTrigger().getTriggerEvent(),
  87                                            getTrigger().getSourceAsDragGestureRecognizer().getSourceActions(),
  88                                            formats,
  89                                            formatMap);
  90 
  91         if (nativeCtxtLocal == 0) {
  92             throw new InvalidDnDOperationException("failed to create native peer");
  93         }
  94 
  95         int[] imageData = null;
  96         Point op = null;
  97 
  98         Image im = getDragImage();
  99         int imageWidth = -1;
 100         int imageHeight = -1;
 101         if (im != null) {
 102             //image is ready (partial images are ok)
 103             try{
 104                 imageWidth = im.getWidth(null);
 105                 imageHeight = im.getHeight(null);
 106                 if (imageWidth < 0 || imageHeight < 0) {
 107                     throw new InvalidDnDOperationException("drag image is not ready");
 108                 }
 109                 //We could get an exception from user code here.
 110                 //"im" and "dragImageOffset" are user-defined objects
 111                 op = getDragImageOffset(); //op could not be null here
 112                 BufferedImage bi = new BufferedImage(
 113                         imageWidth,
 114                         imageHeight,
 115                         BufferedImage.TYPE_INT_ARGB);
 116                 bi.getGraphics().drawImage(im, 0, 0, null);
 117 
 118                 //we can get out-of-memory here
 119                 imageData = ((DataBufferInt)bi.getData().getDataBuffer()).getData();
 120             } catch (Throwable ex) {
 121                 throw new InvalidDnDOperationException("drag image creation problem: " + ex.getMessage());
 122             }
 123         }
 124 
 125         //We shouldn't have user-level exceptions since now.
 126         //Any exception leads to corrupted D'n'D state.
 127         setNativeContext(nativeCtxtLocal);
 128         WDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(trans);
 129 
 130         if (imageData != null) {
 131             doDragDrop(
 132                     getNativeContext(),
 133                     getCursor(),
 134                     imageData,
 135                     imageWidth, imageHeight,
 136                     op.x, op.y);
 137         } else {
 138             doDragDrop(
 139                     getNativeContext(),
 140                     getCursor(),
 141                     null,
 142                     -1, -1,
 143                     0, 0);
 144         }
 145     }
 146 
 147     /**
 148      * downcall into native code
 149      */
 150 
 151     native long createDragSource(Component component,
 152                                  Transferable transferable,
 153                                  InputEvent nativeTrigger,
 154                                  int actions,
 155                                  long[] formats,
 156                                  Map formatMap);
 157 
 158     /**
 159      * downcall into native code
 160      */
 161 
 162     native void doDragDrop(
 163             long nativeCtxt,
 164             Cursor cursor,
 165             int[] imageData,
 166             int imgWidth, int imgHight,
 167             int offsetX, int offsetY);
 168 
 169     protected native void setNativeCursor(long nativeCtxt, Cursor c, int cType);
 170 
 171 }