1 /* 2 * Copyright (c) 1996, 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.awt.datatransfer.DataFlavor; 29 import java.awt.datatransfer.Transferable; 30 import java.awt.datatransfer.UnsupportedFlavorException; 31 import java.io.IOException; 32 import java.util.Map; 33 34 import sun.awt.datatransfer.DataTransferer; 35 import sun.awt.datatransfer.SunClipboard; 36 37 38 /** 39 * A class which interfaces with the Windows clipboard in order to support 40 * data transfer via Clipboard operations. Most of the work is provided by 41 * sun.awt.datatransfer.DataTransferer. 42 * 43 * @author Tom Ball 44 * @author David Mendenhall 45 * @author Danila Sinopalnikov 46 * @author Alexander Gerasimov 47 * 48 * @since JDK1.1 49 */ 50 final class WClipboard extends SunClipboard { 51 52 private boolean isClipboardViewerRegistered; 53 54 WClipboard() { 55 super("System"); 56 } 57 58 @Override 59 public long getID() { 60 return 0; 61 } 62 63 @Override 64 protected void setContentsNative(Transferable contents) { 65 // Don't use delayed Clipboard rendering for the Transferable's data. 66 // If we did that, we would call Transferable.getTransferData on 67 // the Toolkit thread, which is a security hole. 68 // 69 // Get all of the target formats into which the Transferable can be 70 // translated. Then, for each format, translate the data and post 71 // it to the Clipboard. 72 Map <Long, DataFlavor> formatMap = WDataTransferer.getInstance(). 73 getFormatsForTransferable(contents, getDefaultFlavorTable()); 74 75 openClipboard(this); 76 77 try { 78 for (Long format : formatMap.keySet()) { 79 DataFlavor flavor = formatMap.get(format); 80 81 try { 82 byte[] bytes = WDataTransferer.getInstance(). 83 translateTransferable(contents, flavor, format); 84 publishClipboardData(format, bytes); 85 } catch (IOException e) { 86 // Fix 4696186: don't print exception if data with 87 // javaJVMLocalObjectMimeType failed to serialize. 88 // May remove this if-check when 5078787 is fixed. 89 if (!(flavor.isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType) && 90 e instanceof java.io.NotSerializableException)) { 91 e.printStackTrace(); 92 } 93 } 94 } 95 } finally { 96 closeClipboard(); 97 } 98 } 99 100 private void lostSelectionOwnershipImpl() { 101 lostOwnershipImpl(); 102 } 103 104 /** 105 * Currently delayed data rendering is not used for the Windows clipboard, 106 * so there is no native context to clear. 107 */ 108 @Override 109 protected void clearNativeContext() {} 110 111 /** 112 * Call the Win32 OpenClipboard function. If newOwner is non-null, 113 * we also call EmptyClipboard and take ownership. 114 * 115 * @throws IllegalStateException if the clipboard has not been opened 116 */ 117 @Override 118 public native void openClipboard(SunClipboard newOwner) throws IllegalStateException; 119 /** 120 * Call the Win32 CloseClipboard function if we have clipboard ownership, 121 * does nothing if we have not ownership. 122 */ 123 @Override 124 public native void closeClipboard(); 125 /** 126 * Call the Win32 SetClipboardData function. 127 */ 128 private native void publishClipboardData(long format, byte[] bytes); 129 130 private static native void init(); 131 static { 132 init(); 133 } 134 135 @Override 136 protected native long[] getClipboardFormats(); 137 @Override 138 protected native byte[] getClipboardData(long format) throws IOException; 139 140 @Override 141 protected void registerClipboardViewerChecked() { 142 if (!isClipboardViewerRegistered) { 143 registerClipboardViewer(); 144 isClipboardViewerRegistered = true; 145 } 146 } 147 148 private native void registerClipboardViewer(); 149 150 /** 151 * The clipboard viewer (it's the toolkit window) is not unregistered 152 * until the toolkit window disposing since MSDN suggests removing 153 * the window from the clipboard viewer chain just before it is destroyed. 154 */ 155 @Override 156 protected void unregisterClipboardViewerChecked() {} 157 158 /** 159 * Upcall from native code. 160 */ 161 private void handleContentsChanged() { 162 if (!areFlavorListenersRegistered()) { 163 return; 164 } 165 166 long[] formats = null; 167 try { 168 openClipboard(null); 169 formats = getClipboardFormats(); 170 } catch (IllegalStateException exc) { 171 // do nothing to handle the exception, call checkChange(null) 172 } finally { 173 closeClipboard(); 174 } 175 checkChange(formats); 176 } 177 178 /** 179 * The clipboard must be opened. 180 * 181 * @since 1.5 182 */ 183 @Override 184 protected Transferable createLocaleTransferable(long[] formats) throws IOException { 185 boolean found = false; 186 for (int i = 0; i < formats.length; i++) { 187 if (formats[i] == WDataTransferer.CF_LOCALE) { 188 found = true; 189 break; 190 } 191 } 192 if (!found) { 193 return null; 194 } 195 196 byte[] localeData = null; 197 try { 198 localeData = getClipboardData(WDataTransferer.CF_LOCALE); 199 } catch (IOException ioexc) { 200 return null; 201 } 202 203 final byte[] localeDataFinal = localeData; 204 205 return new Transferable() { 206 @Override 207 public DataFlavor[] getTransferDataFlavors() { 208 return new DataFlavor[] { DataTransferer.javaTextEncodingFlavor }; 209 } 210 @Override 211 public boolean isDataFlavorSupported(DataFlavor flavor) { 212 return flavor.equals(DataTransferer.javaTextEncodingFlavor); 213 } 214 @Override 215 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { 216 if (isDataFlavorSupported(flavor)) { 217 return localeDataFinal; 218 } 219 throw new UnsupportedFlavorException(flavor); 220 } 221 }; 222 } 223 }