1 /* 2 * Copyright (c) 1997, 2014, 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.io.InputStream; 29 import java.io.FileInputStream; 30 import java.io.FileNotFoundException; 31 import java.io.IOException; 32 33 import sun.awt.PeerEvent; 34 import sun.awt.SunToolkit; 35 import sun.awt.dnd.SunDropTargetContextPeer; 36 import sun.awt.dnd.SunDropTargetEvent; 37 38 /** 39 * <p> 40 * The WDropTargetContextPeer class is the class responsible for handling 41 * the interaction between the win32 DnD system and Java. 42 * </p> 43 * 44 * 45 */ 46 47 final class WDropTargetContextPeer extends SunDropTargetContextPeer { 48 /** 49 * create the peer typically upcall from C++ 50 */ 51 getWDropTargetContextPeer()52 static WDropTargetContextPeer getWDropTargetContextPeer() { 53 return new WDropTargetContextPeer(); 54 } 55 56 /** 57 * create the peer 58 */ 59 WDropTargetContextPeer()60 private WDropTargetContextPeer() { 61 super(); 62 } 63 64 /** 65 * upcall to encapsulate file transfer 66 */ 67 getFileStream(String file, long stgmedium)68 private static FileInputStream getFileStream(String file, long stgmedium) 69 throws IOException 70 { 71 return new WDropTargetContextPeerFileStream(file, stgmedium); 72 } 73 74 /** 75 * upcall to encapsulate IStream buffer transfer 76 */ 77 getIStream(long istream)78 private static Object getIStream(long istream) throws IOException { 79 return new WDropTargetContextPeerIStream(istream); 80 } 81 82 @Override getNativeData(long format)83 protected Object getNativeData(long format) { 84 return getData(getNativeDragContext(), format); 85 } 86 87 /** 88 * signal drop complete 89 */ 90 91 @Override doDropDone(boolean success, int dropAction, boolean isLocal)92 protected void doDropDone(boolean success, int dropAction, 93 boolean isLocal) { 94 dropDone(getNativeDragContext(), success, dropAction); 95 } 96 97 @Override eventPosted(final SunDropTargetEvent e)98 protected void eventPosted(final SunDropTargetEvent e) { 99 if (e.getID() != SunDropTargetEvent.MOUSE_DROPPED) { 100 Runnable runnable = new Runnable() { 101 @Override 102 public void run() { 103 e.getDispatcher().unregisterAllEvents(); 104 } 105 }; 106 // NOTE: this PeerEvent must be a NORM_PRIORITY event to be 107 // dispatched after this SunDropTargetEvent, but before the next 108 // one, so we should pass zero flags. 109 PeerEvent peerEvent = new PeerEvent(e.getSource(), runnable, 0); 110 SunToolkit.executeOnEventHandlerThread(peerEvent); 111 } 112 } 113 114 /** 115 * downcall to bind transfer data. 116 */ 117 getData(long nativeContext, long format)118 private native Object getData(long nativeContext, long format); 119 120 /** 121 * downcall to notify that drop is complete 122 */ 123 dropDone(long nativeContext, boolean success, int action)124 private native void dropDone(long nativeContext, boolean success, int action); 125 } 126 127 /** 128 * package private class to handle file transfers 129 */ 130 131 final class WDropTargetContextPeerFileStream extends FileInputStream { 132 133 /** 134 * construct file input stream 135 */ 136 WDropTargetContextPeerFileStream(String name, long stgmedium)137 WDropTargetContextPeerFileStream(String name, long stgmedium) 138 throws FileNotFoundException 139 { 140 super(name); 141 142 this.stgmedium = stgmedium; 143 } 144 145 /** 146 * close 147 */ 148 149 @Override close()150 public void close() throws IOException { 151 if (stgmedium != 0) { 152 super.close(); 153 freeStgMedium(stgmedium); 154 stgmedium = 0; 155 } 156 } 157 158 /** 159 * free underlying windows data structure 160 */ 161 freeStgMedium(long stgmedium)162 private native void freeStgMedium(long stgmedium); 163 164 /* 165 * fields 166 */ 167 168 private long stgmedium; 169 } 170 171 /** 172 * Package private class to access IStream objects 173 */ 174 175 final class WDropTargetContextPeerIStream extends InputStream { 176 177 /** 178 * construct a WDropTargetContextPeerIStream wrapper 179 */ 180 WDropTargetContextPeerIStream(long istream)181 WDropTargetContextPeerIStream(long istream) throws IOException { 182 super(); 183 184 if (istream == 0) throw new IOException("No IStream"); 185 186 this.istream = istream; 187 } 188 189 /** 190 * @return bytes available 191 */ 192 193 @Override available()194 public int available() throws IOException { 195 if (istream == 0) throw new IOException("No IStream"); 196 return Available(istream); 197 } 198 Available(long istream)199 private native int Available(long istream); 200 201 /** 202 * read 203 */ 204 205 @Override read()206 public int read() throws IOException { 207 if (istream == 0) throw new IOException("No IStream"); 208 return Read(istream); 209 } 210 Read(long istream)211 private native int Read(long istream) throws IOException; 212 213 /** 214 * read into buffer 215 */ 216 217 @Override read(byte[] b, int off, int len)218 public int read(byte[] b, int off, int len) throws IOException { 219 if (istream == 0) throw new IOException("No IStream"); 220 return ReadBytes(istream, b, off, len); 221 } 222 ReadBytes(long istream, byte[] b, int off, int len)223 private native int ReadBytes(long istream, byte[] b, int off, int len) throws IOException; 224 225 /** 226 * close 227 */ 228 229 @Override close()230 public void close() throws IOException { 231 if (istream != 0) { 232 super.close(); 233 Close(istream); 234 istream = 0; 235 } 236 } 237 Close(long istream)238 private native void Close(long istream); 239 240 /* 241 * fields 242 */ 243 244 private long istream; 245 } 246