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