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 formatMap = WDataTransferer.getInstance(). 75 getFormatsForTransferable(contents, flavorMap); 76 77 openClipboard(this); 78 79 try { 80 for (Iterator iter = formatMap.keySet().iterator(); 81 iter.hasNext(); ) { 82 Long lFormat = (Long)iter.next(); 83 long format = lFormat.longValue(); 84 DataFlavor flavor = (DataFlavor)formatMap.get(lFormat); 85 86 try { 87 byte[] bytes = WDataTransferer.getInstance(). 88 translateTransferable(contents, flavor, format); 89 publishClipboardData(format, bytes); 90 } catch (IOException e) { 91 // Fix 4696186: don't print exception if data with 92 // javaJVMLocalObjectMimeType failed to serialize. 93 // May remove this if-check when 5078787 is fixed. 94 if (!(flavor.isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType) && 95 e instanceof java.io.NotSerializableException)) { 96 e.printStackTrace(); 97 } 98 } 99 } 100 } finally { 101 closeClipboard(); 102 } 103 } 104 105 private void lostSelectionOwnershipImpl() { 106 lostOwnershipImpl(); 107 } 108 109 /** 110 * Currently delayed data rendering is not used for the Windows clipboard, 111 * so there is no native context to clear. 112 */ 113 protected void clearNativeContext() {} 114 115 /** 116 * Call the Win32 OpenClipboard function. If newOwner is non-null, 117 * we also call EmptyClipboard and take ownership. 118 * 119 * @throws IllegalStateException if the clipboard has not been opened 120 */ 121 public native void openClipboard(SunClipboard newOwner) throws IllegalStateException; 122 /** 123 * Call the Win32 CloseClipboard function if we have clipboard ownership, 124 * does nothing if we have not ownership. 125 */ 126 public native void closeClipboard(); 127 /** 128 * Call the Win32 SetClipboardData function. 129 */ 130 private native void publishClipboardData(long format, byte[] bytes); 131 132 private static native void init(); 133 static { 134 init(); 135 } 136 137 protected native long[] getClipboardFormats(); 138 protected native byte[] getClipboardData(long format) throws IOException; 139 140 protected void registerClipboardViewerChecked() { 141 if (!isClipboardViewerRegistered) { 142 registerClipboardViewer(); 143 isClipboardViewerRegistered = true; 144 } 145 } 146 147 private native void registerClipboardViewer(); 148 149 /** 150 * The clipboard viewer (it's the toolkit window) is not unregistered 151 * until the toolkit window disposing since MSDN suggests removing 152 * the window from the clipboard viewer chain just before it is destroyed. 153 */ 154 protected void unregisterClipboardViewerChecked() {} 155 156 /** 157 * Upcall from native code. 158 */ 159 private void handleContentsChanged() { 160 if (!areFlavorListenersRegistered()) { 161 return; 162 } 163 164 long[] formats = null; 165 try { 166 openClipboard(null); 167 formats = getClipboardFormats(); 168 } catch (IllegalStateException exc) { 169 // do nothing to handle the exception, call checkChange(null) 170 } finally { 171 closeClipboard(); 172 } 173 checkChange(formats); 174 } 175 176 /** 177 * The clipboard must be opened. 178 * 179 * @since 1.5 180 */ 181 protected Transferable createLocaleTransferable(long[] formats) throws IOException { 182 boolean found = false; 183 for (int i = 0; i < formats.length; i++) { 184 if (formats[i] == WDataTransferer.CF_LOCALE) { 185 found = true; 186 break; 187 } 188 } 189 if (!found) { 190 return null; 191 } 192 193 byte[] localeData = null; 194 try { 195 localeData = getClipboardData(WDataTransferer.CF_LOCALE); 196 } catch (IOException ioexc) { 197 return null; 198 } 199 200 final byte[] localeDataFinal = localeData; 201 202 return new Transferable() { 203 public DataFlavor[] getTransferDataFlavors() { 204 return new DataFlavor[] { DataTransferer.javaTextEncodingFlavor }; 205 } 206 public boolean isDataFlavorSupported(DataFlavor flavor) { 207 return flavor.equals(DataTransferer.javaTextEncodingFlavor); 208 } 209 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { 210 if (isDataFlavorSupported(flavor)) { 211 return localeDataFinal; 212 } 213 throw new UnsupportedFlavorException(flavor); 214 } 215 }; 216 } 217 218 }