blob: 3e82560a5cf33af82ba9fce92e316b7e7ae41279 [file] [log] [blame]
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt.windows;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.Map;
import sun.awt.datatransfer.DataTransferer;
import sun.awt.datatransfer.SunClipboard;
/**
* A class which interfaces with the Windows clipboard in order to support
* data transfer via Clipboard operations. Most of the work is provided by
* sun.awt.datatransfer.DataTransferer.
*
* @author Tom Ball
* @author David Mendenhall
* @author Danila Sinopalnikov
* @author Alexander Gerasimov
*
* @since 1.1
*/
final class WClipboard extends SunClipboard {
private boolean isClipboardViewerRegistered;
WClipboard() {
super("System");
}
@Override
public long getID() {
return 0;
}
@Override
protected void setContentsNative(Transferable contents) {
// Don't use delayed Clipboard rendering for the Transferable's data.
// If we did that, we would call Transferable.getTransferData on
// the Toolkit thread, which is a security hole.
//
// Get all of the target formats into which the Transferable can be
// translated. Then, for each format, translate the data and post
// it to the Clipboard.
Map <Long, DataFlavor> formatMap = WDataTransferer.getInstance().
getFormatsForTransferable(contents, getDefaultFlavorTable());
openClipboard(this);
try {
for (Long format : formatMap.keySet()) {
DataFlavor flavor = formatMap.get(format);
try {
byte[] bytes = WDataTransferer.getInstance().
translateTransferable(contents, flavor, format);
publishClipboardData(format, bytes);
} catch (IOException e) {
// Fix 4696186: don't print exception if data with
// javaJVMLocalObjectMimeType failed to serialize.
// May remove this if-check when 5078787 is fixed.
if (!(flavor.isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType) &&
e instanceof java.io.NotSerializableException)) {
e.printStackTrace();
}
}
}
} finally {
closeClipboard();
}
}
private void lostSelectionOwnershipImpl() {
lostOwnershipImpl();
}
/**
* Currently delayed data rendering is not used for the Windows clipboard,
* so there is no native context to clear.
*/
@Override
protected void clearNativeContext() {}
/**
* Call the Win32 OpenClipboard function. If newOwner is non-null,
* we also call EmptyClipboard and take ownership.
*
* @throws IllegalStateException if the clipboard has not been opened
*/
@Override
public native void openClipboard(SunClipboard newOwner) throws IllegalStateException;
/**
* Call the Win32 CloseClipboard function if we have clipboard ownership,
* does nothing if we have not ownership.
*/
@Override
public native void closeClipboard();
/**
* Call the Win32 SetClipboardData function.
*/
private native void publishClipboardData(long format, byte[] bytes);
private static native void init();
static {
init();
}
@Override
protected native long[] getClipboardFormats();
@Override
protected native byte[] getClipboardData(long format) throws IOException;
@Override
protected void registerClipboardViewerChecked() {
if (!isClipboardViewerRegistered) {
registerClipboardViewer();
isClipboardViewerRegistered = true;
}
}
private native void registerClipboardViewer();
/**
* The clipboard viewer (it's the toolkit window) is not unregistered
* until the toolkit window disposing since MSDN suggests removing
* the window from the clipboard viewer chain just before it is destroyed.
*/
@Override
protected void unregisterClipboardViewerChecked() {}
/**
* Upcall from native code.
*/
private void handleContentsChanged() {
if (!areFlavorListenersRegistered()) {
return;
}
long[] formats = null;
try {
openClipboard(null);
formats = getClipboardFormats();
} catch (IllegalStateException exc) {
// do nothing to handle the exception, call checkChange(null)
} finally {
closeClipboard();
}
checkChange(formats);
}
/**
* The clipboard must be opened.
*
* @since 1.5
*/
@Override
protected Transferable createLocaleTransferable(long[] formats) throws IOException {
boolean found = false;
for (int i = 0; i < formats.length; i++) {
if (formats[i] == WDataTransferer.CF_LOCALE) {
found = true;
break;
}
}
if (!found) {
return null;
}
byte[] localeData = null;
try {
localeData = getClipboardData(WDataTransferer.CF_LOCALE);
} catch (IOException ioexc) {
return null;
}
final byte[] localeDataFinal = localeData;
return new Transferable() {
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { DataTransferer.javaTextEncodingFlavor };
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(DataTransferer.javaTextEncodingFlavor);
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
if (isDataFlavorSupported(flavor)) {
return localeDataFinal;
}
throw new UnsupportedFlavorException(flavor);
}
};
}
}