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