/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* A class which interfaces with the X11 selection service.
*/
public final class XSelection {
/* Maps atoms to XSelection instances. */
/* Prevents from parallel selection data request processing. */
/* The property in which the owner should place the requested data. */
/* The maximal length of the property data. */
/*
* The maximum data size for ChangeProperty request.
* 100 is for the structure prepended to the request.
*/
public static final int MAX_PROPERTY_SIZE;
static {
try {
} finally {
}
}
/* The PropertyNotify event handler for incremental data transfer. */
new IncrementalTransferHandler();
/* The context for the current request - protected with awtLock. */
// The orders of the lock acquisition:
// XClipboard -> XSelection -> awtLock.
// lock -> awtLock.
/* The X atom for the underlying selection. */
/*
* Owner-related variables - protected with synchronized (this).
*/
/* The contents supplied by the current owner. */
/* The format-to-flavor map for the current owner. */
/* The formats supported by the current owner was set. */
/* The AppContext in which the current owner was set. */
// The X server time of the last XConvertSelection() call;
// protected with 'lock' and awtLock.
private static long lastRequestServerTime;
/* The time at which the current owner was set. */
// True if we are the owner of this selection.
private boolean isOwner;
static {
new SelectionEventHandler());
}
/*
* Returns the XSelection object for the specified selection atom or
* <code>null</code> if none exists.
*/
}
/**
* Creates a selection object.
*
* @param atom the selection atom.
* @param clpbrd the corresponding clipoboard
* @exception NullPointerException if atom is <code>null</code>.
*/
throw new NullPointerException("Null atom");
}
}
return selectionAtom;
}
{
// ICCCM prescribes that CurrentTime should not be used for SetSelectionOwner.
}
this.ownershipTime = time;
try {
{
reset();
return false;
}
setOwnerProp(true);
return true;
} finally {
}
}
/**
* Blocks the current thread till SelectionNotify or PropertyNotify (in case of INCR transfer) arrives.
*/
private static void waitForSelectionNotify(WindowPropertyGetter dataGetter) throws InterruptedException {
try {
do {
} while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + UNIXToolkit.getDatatransferTimeout());
} finally {
}
}
/*
* Returns the list of atoms that represent the targets for which an attempt
* to convert the current selection will succeed.
*/
if (XToolkit.isToolkitThread()) {
throw new Error("UNIMPLEMENTED");
}
synchronized (lock) {
true, XConstants.AnyPropertyType);
try {
try {
getSelectionAtom().getAtom(),
time);
// If the owner doesn't respond within the
// SELECTION_TIMEOUT, we report conversion failure.
try {
} catch (InterruptedException ie) {
return new long[0];
} finally {
}
} finally {
}
} finally {
}
}
return targets;
}
{
// we accept property with TARGETS type to be compatible with old jdks
// see 6607163
if (count > 0) {
}
}
}
}
/*
* Requests the selection data in the specified format and returns
* the data provided by the owner.
*/
if (XToolkit.isToolkitThread()) {
throw new Error("UNIMPLEMENTED");
}
synchronized (lock) {
false, // don't delete to handle INCR properly.
try {
try {
getSelectionAtom().getAtom(),
time);
// If the owner doesn't respond within the
// SELECTION_TIMEOUT, we report conversion failure.
try {
} catch (InterruptedException ie) {
return new byte[0];
} finally {
}
} finally {
}
// Handle incremental transfer.
if (dataGetter.getActualType() ==
throw new IOException("Unsupported INCR format: " +
}
if (count <= 0) {
throw new IOException("INCR data is missed.");
}
int len = 0;
{
// Following Xt sources use the last element.
if (longLength <= 0) {
return new byte[0];
}
throw new IOException("Can't handle large data block: "
+ longLength + " bytes");
}
len = (int)longLength;
}
while (true) {
0, MAX_LENGTH, false,
try {
try {
// If the owner doesn't respond within the
// SELECTION_TIMEOUT, we terminate incremental
// transfer.
} catch (InterruptedException ie) {
break;
} finally {
}
throw new IOException("Unsupported data format: " +
}
if (count == 0) {
break;
}
if (count > 0) {
}
}
} finally {
}
}
} else {
try {
} finally {
}
throw new IOException("Unsupported data format: " +
}
if (count > 0) {
}
}
}
} finally {
}
}
}
throws IOException
{
// The order of checks is important because a property getter
// has not been executed in case of timeout as well as in case of
// changed selection owner.
if (propertyGetter.isDisposed()) {
throw new IOException("Owner failed to convert data");
}
// The owner didn't respond - terminate the transfer.
if (!propertyGetter.isExecuted()) {
throw new IOException("Owner timed out");
}
}
// To be MT-safe this method should be called under awtLock.
boolean isOwner() {
return isOwner;
}
// To be MT-safe this method should be called under awtLock.
private void setOwnerProp(boolean f) {
isOwner = f;
}
private void lostOwnership() {
setOwnerProp(false);
}
public synchronized void reset() {
appContext = null;
ownershipTime = 0;
}
// Converts the data to the 'format' and if the conversion succeeded stores
// the data in the 'property' on the 'requestor' window.
// Returns true if the conversion succeeded.
long nativeDataPtr = 0;
int count = 0;
try {
} catch (IOException ioe) {
return false;
}
return false;
}
try {
if (count > 0) {
if (count <= MAX_PROPERTY_SIZE) {
} else {
// Initiate incremental data transfer.
byteData);
dataFormat = 32;
count = 1;
}
}
try {
} finally {
}
} finally {
if (nativeDataPtr != 0) {
nativeDataPtr = 0;
}
}
return true;
}
boolean conversionSucceeded = false;
if (ownershipTime != 0 &&
{
// Handle MULTIPLE requests as per ICCCM.
} else {
// Support for obsolete clients as per ICCCM.
}
} else {
}
}
}
if (!conversionSucceeded) {
// None property indicates conversion failure.
}
try {
xse.set_send_event(true);
try {
} finally {
}
} finally {
}
}
// The property cannot be None for a MULTIPLE request.
return false;
}
boolean conversionSucceeded = false;
// First retrieve the list of requested targets.
0, MAX_LENGTH, false,
try {
boolean writeBack = false;
for (int i = 0; i < count; i++) {
// To report failure, we should replace the
// target atom with 0 in the MULTIPLE property.
writeBack = true;
}
}
if (writeBack) {
try {
wpg.getActualType(),
wpg.getNumberOfItems());
} finally {
}
}
conversionSucceeded = true;
}
} finally {
}
return conversionSucceeded;
}
throws IllegalStateException
{
boolean conversionSucceeded = false;
// Use a local copy to avoid synchronization.
long[] formatsLocal = formats;
if (formatsLocal == null) {
throw new IllegalStateException("Not an owner.");
}
long nativeDataPtr = 0;
try {
final int dataFormat = 32;
if (count > 0) {
}
conversionSucceeded = true;
try {
} finally {
}
} finally {
if (nativeDataPtr != 0) {
nativeDataPtr = 0;
}
}
return conversionSucceeded;
}
OwnershipListener l = null;
synchronized (stateLock) {
l = ownershipListener;
}
if (null != l) {
}
}
synchronized (stateLock) {
ownershipListener = l;
}
}
void unregisterOwnershipListener() {
synchronized (stateLock) {
}
}
case XConstants.SelectionNotify: {
try {
// Ignore the SelectionNotify event if it is not the response to our last request.
// The property will be None in case of convertion failure.
}
}
} finally {
}
break;
}
case XConstants.SelectionRequest: {
}
break;
}
case XConstants.SelectionClear: {
}
try {
} finally {
}
break;
}
}
}
};
private final long requestor;
private final long property;
private final long target;
private final int format;
private final byte[] data;
// NOTE: formats other than 8 are not supported.
if (format != 8) {
}
try {
try {
} finally {
}
} finally {
}
}
case XConstants.PropertyNotify:
long nativeDataPtr = 0;
if (count > MAX_PROPERTY_SIZE) {
}
if (count > 0) {
for (int i = 0; i < count; i++) {
}
} else {
assert (count == 0);
// All data has been transferred.
// This zero-length data indicates end of transfer.
}
try {
} finally {
}
if (nativeDataPtr != 0) {
nativeDataPtr = 0;
}
}
}
}
}
case XConstants.PropertyNotify:
try {
if (propertyGetter != null) {
}
} finally {
}
}
break;
}
}
};
}