feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
1289
jdkSrc/jdk8/sun/awt/AWTAccessor.java
Normal file
1289
jdkSrc/jdk8/sun/awt/AWTAccessor.java
Normal file
File diff suppressed because it is too large
Load Diff
398
jdkSrc/jdk8/sun/awt/AWTAutoShutdown.java
Normal file
398
jdkSrc/jdk8/sun/awt/AWTAutoShutdown.java
Normal file
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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;
|
||||
|
||||
import java.awt.AWTEvent;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import sun.util.logging.PlatformLogger;
|
||||
import sun.misc.ThreadGroupUtils;
|
||||
|
||||
/**
|
||||
* This class is to let AWT shutdown automatically when a user is done
|
||||
* with AWT. It tracks AWT state using the following parameters:
|
||||
* <ul>
|
||||
* <li><code>peerMap</code> - the map between the existing peer objects
|
||||
* and their associated targets
|
||||
* <li><code>toolkitThreadBusy</code> - whether the toolkit thread
|
||||
* is waiting for a new native event to appear in its queue
|
||||
* or is dispatching an event
|
||||
* <li><code>busyThreadSet</code> - a set of all the event dispatch
|
||||
* threads that are busy at this moment, i.e. those that are not
|
||||
* waiting for a new event to appear in their event queue.
|
||||
* </ul><p>
|
||||
* AWT is considered to be in ready-to-shutdown state when
|
||||
* <code>peerMap</code> is empty and <code>toolkitThreadBusy</code>
|
||||
* is false and <code>busyThreadSet</code> is empty.
|
||||
* The internal AWTAutoShutdown logic secures that the single non-daemon
|
||||
* thread (<code>blockerThread</code>) is running when AWT is not in
|
||||
* ready-to-shutdown state. This blocker thread is to prevent AWT from
|
||||
* exiting since the toolkit thread is now daemon and all the event
|
||||
* dispatch threads are started only when needed. Once it is detected
|
||||
* that AWT is in ready-to-shutdown state this blocker thread waits
|
||||
* for a certain timeout and if AWT state doesn't change during timeout
|
||||
* this blocker thread terminates all the event dispatch threads and
|
||||
* exits.
|
||||
*/
|
||||
public final class AWTAutoShutdown implements Runnable {
|
||||
|
||||
private static final AWTAutoShutdown theInstance = new AWTAutoShutdown();
|
||||
|
||||
/**
|
||||
* This lock object is used to synchronize shutdown operations.
|
||||
*/
|
||||
private final Object mainLock = new Object();
|
||||
|
||||
/**
|
||||
* This lock object is to secure that when a new blocker thread is
|
||||
* started it will be the first who acquire the main lock after
|
||||
* the thread that created the new blocker released the main lock
|
||||
* by calling lock.wait() to wait for the blocker to start.
|
||||
*/
|
||||
private final Object activationLock = new Object();
|
||||
|
||||
/**
|
||||
* This set keeps references to all the event dispatch threads that
|
||||
* are busy at this moment, i.e. those that are not waiting for a
|
||||
* new event to appear in their event queue.
|
||||
* Access is synchronized on the main lock object.
|
||||
*/
|
||||
private final Set<Thread> busyThreadSet = new HashSet<>(7);
|
||||
|
||||
/**
|
||||
* Indicates whether the toolkit thread is waiting for a new native
|
||||
* event to appear or is dispatching an event.
|
||||
*/
|
||||
private boolean toolkitThreadBusy = false;
|
||||
|
||||
/**
|
||||
* This is a map between components and their peers.
|
||||
* we should work with in under activationLock&mainLock lock.
|
||||
*/
|
||||
private final Map<Object, Object> peerMap = new IdentityHashMap<>();
|
||||
|
||||
/**
|
||||
* References the alive non-daemon thread that is currently used
|
||||
* for keeping AWT from exiting.
|
||||
*/
|
||||
private Thread blockerThread = null;
|
||||
|
||||
/**
|
||||
* We need this flag to secure that AWT state hasn't changed while
|
||||
* we were waiting for the safety timeout to pass.
|
||||
*/
|
||||
private boolean timeoutPassed = false;
|
||||
|
||||
/**
|
||||
* Once we detect that AWT is ready to shutdown we wait for a certain
|
||||
* timeout to pass before stopping event dispatch threads.
|
||||
*/
|
||||
private static final int SAFETY_TIMEOUT = 1000;
|
||||
|
||||
/**
|
||||
* Constructor method is intentionally made private to secure
|
||||
* a single instance. Use getInstance() to reference it.
|
||||
*
|
||||
* @see AWTAutoShutdown#getInstance
|
||||
*/
|
||||
private AWTAutoShutdown() {}
|
||||
|
||||
/**
|
||||
* Returns reference to a single AWTAutoShutdown instance.
|
||||
*/
|
||||
public static AWTAutoShutdown getInstance() {
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that the toolkit thread is not waiting for a native event
|
||||
* to appear in its queue.
|
||||
*
|
||||
* @see AWTAutoShutdown#notifyToolkitThreadFree
|
||||
* @see AWTAutoShutdown#setToolkitBusy
|
||||
* @see AWTAutoShutdown#isReadyToShutdown
|
||||
*/
|
||||
public static void notifyToolkitThreadBusy() {
|
||||
getInstance().setToolkitBusy(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that the toolkit thread is waiting for a native event
|
||||
* to appear in its queue.
|
||||
*
|
||||
* @see AWTAutoShutdown#notifyToolkitThreadFree
|
||||
* @see AWTAutoShutdown#setToolkitBusy
|
||||
* @see AWTAutoShutdown#isReadyToShutdown
|
||||
*/
|
||||
public static void notifyToolkitThreadFree() {
|
||||
getInstance().setToolkitBusy(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a specified thread to the set of busy event dispatch threads.
|
||||
* If this set already contains the specified thread or the thread is null,
|
||||
* the call leaves this set unchanged and returns silently.
|
||||
*
|
||||
* @param thread thread to be added to this set, if not present.
|
||||
* @see AWTAutoShutdown#notifyThreadFree
|
||||
* @see AWTAutoShutdown#isReadyToShutdown
|
||||
*/
|
||||
public void notifyThreadBusy(final Thread thread) {
|
||||
if (thread == null) {
|
||||
return;
|
||||
}
|
||||
synchronized (activationLock) {
|
||||
synchronized (mainLock) {
|
||||
if (blockerThread == null) {
|
||||
activateBlockerThread();
|
||||
} else if (isReadyToShutdown()) {
|
||||
mainLock.notifyAll();
|
||||
timeoutPassed = false;
|
||||
}
|
||||
busyThreadSet.add(thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a specified thread from the set of busy event dispatch threads.
|
||||
* If this set doesn't contain the specified thread or the thread is null,
|
||||
* the call leaves this set unchanged and returns silently.
|
||||
*
|
||||
* @param thread thread to be removed from this set, if present.
|
||||
* @see AWTAutoShutdown#notifyThreadBusy
|
||||
* @see AWTAutoShutdown#isReadyToShutdown
|
||||
*/
|
||||
public void notifyThreadFree(final Thread thread) {
|
||||
if (thread == null) {
|
||||
return;
|
||||
}
|
||||
synchronized (activationLock) {
|
||||
synchronized (mainLock) {
|
||||
busyThreadSet.remove(thread);
|
||||
if (isReadyToShutdown()) {
|
||||
mainLock.notifyAll();
|
||||
timeoutPassed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that the peermap has been updated, that means a new peer
|
||||
* has been created or some existing peer has been disposed.
|
||||
*
|
||||
* @see AWTAutoShutdown#isReadyToShutdown
|
||||
*/
|
||||
void notifyPeerMapUpdated() {
|
||||
synchronized (activationLock) {
|
||||
synchronized (mainLock) {
|
||||
if (!isReadyToShutdown() && blockerThread == null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
||||
activateBlockerThread();
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
mainLock.notifyAll();
|
||||
timeoutPassed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether AWT is currently in ready-to-shutdown state.
|
||||
* AWT is considered to be in ready-to-shutdown state if
|
||||
* <code>peerMap</code> is empty and <code>toolkitThreadBusy</code>
|
||||
* is false and <code>busyThreadSet</code> is empty.
|
||||
*
|
||||
* @return true if AWT is in ready-to-shutdown state.
|
||||
*/
|
||||
private boolean isReadyToShutdown() {
|
||||
return (!toolkitThreadBusy &&
|
||||
peerMap.isEmpty() &&
|
||||
busyThreadSet.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify about the toolkit thread state change.
|
||||
*
|
||||
* @param busy true if the toolkit thread state changes from idle
|
||||
* to busy.
|
||||
* @see AWTAutoShutdown#notifyToolkitThreadBusy
|
||||
* @see AWTAutoShutdown#notifyToolkitThreadFree
|
||||
* @see AWTAutoShutdown#isReadyToShutdown
|
||||
*/
|
||||
private void setToolkitBusy(final boolean busy) {
|
||||
if (busy != toolkitThreadBusy) {
|
||||
synchronized (activationLock) {
|
||||
synchronized (mainLock) {
|
||||
if (busy != toolkitThreadBusy) {
|
||||
if (busy) {
|
||||
if (blockerThread == null) {
|
||||
activateBlockerThread();
|
||||
} else if (isReadyToShutdown()) {
|
||||
mainLock.notifyAll();
|
||||
timeoutPassed = false;
|
||||
}
|
||||
toolkitThreadBusy = busy;
|
||||
} else {
|
||||
toolkitThreadBusy = busy;
|
||||
if (isReadyToShutdown()) {
|
||||
mainLock.notifyAll();
|
||||
timeoutPassed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the Runnable interface.
|
||||
* Incapsulates the blocker thread functionality.
|
||||
*
|
||||
* @see AWTAutoShutdown#isReadyToShutdown
|
||||
*/
|
||||
public void run() {
|
||||
Thread currentThread = Thread.currentThread();
|
||||
boolean interrupted = false;
|
||||
synchronized (mainLock) {
|
||||
try {
|
||||
/* Notify that the thread is started. */
|
||||
mainLock.notifyAll();
|
||||
while (blockerThread == currentThread) {
|
||||
mainLock.wait();
|
||||
timeoutPassed = false;
|
||||
/*
|
||||
* This loop is introduced to handle the following case:
|
||||
* it is possible that while we are waiting for the
|
||||
* safety timeout to pass AWT state can change to
|
||||
* not-ready-to-shutdown and back to ready-to-shutdown.
|
||||
* In this case we have to wait once again.
|
||||
* NOTE: we shouldn't break into the outer loop
|
||||
* in this case, since we may never be notified
|
||||
* in an outer infinite wait at this point.
|
||||
*/
|
||||
while (isReadyToShutdown()) {
|
||||
if (timeoutPassed) {
|
||||
timeoutPassed = false;
|
||||
blockerThread = null;
|
||||
break;
|
||||
}
|
||||
timeoutPassed = true;
|
||||
mainLock.wait(SAFETY_TIMEOUT);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
interrupted = true;
|
||||
} finally {
|
||||
if (blockerThread == currentThread) {
|
||||
blockerThread = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!interrupted) {
|
||||
AppContext.stopEventDispatchThreads();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static AWTEvent getShutdownEvent() {
|
||||
return new AWTEvent(getInstance(), 0) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and starts a new blocker thread. Doesn't return until
|
||||
* the new blocker thread starts.
|
||||
*
|
||||
* Must be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION}
|
||||
*/
|
||||
private void activateBlockerThread() {
|
||||
Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, "AWT-Shutdown");
|
||||
thread.setContextClassLoader(null);
|
||||
thread.setDaemon(false);
|
||||
blockerThread = thread;
|
||||
thread.start();
|
||||
try {
|
||||
/* Wait for the blocker thread to start. */
|
||||
mainLock.wait();
|
||||
} catch (InterruptedException e) {
|
||||
System.err.println("AWT blocker activation interrupted:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
final void registerPeer(final Object target, final Object peer) {
|
||||
synchronized (activationLock) {
|
||||
synchronized (mainLock) {
|
||||
peerMap.put(target, peer);
|
||||
notifyPeerMapUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final void unregisterPeer(final Object target, final Object peer) {
|
||||
synchronized (activationLock) {
|
||||
synchronized (mainLock) {
|
||||
if (peerMap.get(target) == peer) {
|
||||
peerMap.remove(target);
|
||||
notifyPeerMapUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Object getPeer(final Object target) {
|
||||
synchronized (activationLock) {
|
||||
synchronized (mainLock) {
|
||||
return peerMap.get(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final void dumpPeers(final PlatformLogger aLog) {
|
||||
if (aLog.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
synchronized (activationLock) {
|
||||
synchronized (mainLock) {
|
||||
aLog.fine("Mapped peers:");
|
||||
for (Object key : peerMap.keySet()) {
|
||||
aLog.fine(key + "->" + peerMap.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // class AWTAutoShutdown
|
||||
140
jdkSrc/jdk8/sun/awt/AWTCharset.java
Normal file
140
jdkSrc/jdk8/sun/awt/AWTCharset.java
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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;
|
||||
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.*;
|
||||
|
||||
|
||||
//This class delegates all invokes to the charset "javaCs" if
|
||||
//its subclasses do not provide their own en/decode solution.
|
||||
|
||||
public class AWTCharset extends Charset {
|
||||
protected Charset awtCs;
|
||||
protected Charset javaCs;
|
||||
|
||||
public AWTCharset(String awtCsName, Charset javaCs) {
|
||||
super(awtCsName, null);
|
||||
this.javaCs = javaCs;
|
||||
this.awtCs = this;
|
||||
}
|
||||
|
||||
public boolean contains(Charset cs) {
|
||||
if (javaCs == null) return false;
|
||||
return javaCs.contains(cs);
|
||||
}
|
||||
|
||||
public CharsetEncoder newEncoder() {
|
||||
if (javaCs == null)
|
||||
throw new Error("Encoder is not supported by this Charset");
|
||||
return new Encoder(javaCs.newEncoder());
|
||||
}
|
||||
|
||||
public CharsetDecoder newDecoder() {
|
||||
if (javaCs == null)
|
||||
throw new Error("Decoder is not supported by this Charset");
|
||||
return new Decoder(javaCs.newDecoder());
|
||||
}
|
||||
|
||||
public class Encoder extends CharsetEncoder {
|
||||
protected CharsetEncoder enc;
|
||||
protected Encoder () {
|
||||
this(javaCs.newEncoder());
|
||||
}
|
||||
protected Encoder (CharsetEncoder enc) {
|
||||
super(awtCs,
|
||||
enc.averageBytesPerChar(),
|
||||
enc.maxBytesPerChar());
|
||||
this.enc = enc;
|
||||
}
|
||||
public boolean canEncode(char c) {
|
||||
return enc.canEncode(c);
|
||||
}
|
||||
public boolean canEncode(CharSequence cs) {
|
||||
return enc.canEncode(cs);
|
||||
}
|
||||
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
|
||||
return enc.encode(src, dst, true);
|
||||
}
|
||||
protected CoderResult implFlush(ByteBuffer out) {
|
||||
return enc.flush(out);
|
||||
}
|
||||
protected void implReset() {
|
||||
enc.reset();
|
||||
}
|
||||
protected void implReplaceWith(byte[] newReplacement) {
|
||||
if (enc != null)
|
||||
enc.replaceWith(newReplacement);
|
||||
}
|
||||
protected void implOnMalformedInput(CodingErrorAction newAction) {
|
||||
enc.onMalformedInput(newAction);
|
||||
}
|
||||
protected void implOnUnmappableCharacter(CodingErrorAction newAction) {
|
||||
enc.onUnmappableCharacter(newAction);
|
||||
}
|
||||
public boolean isLegalReplacement(byte[] repl) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class Decoder extends CharsetDecoder {
|
||||
protected CharsetDecoder dec;
|
||||
private String nr;
|
||||
|
||||
protected Decoder () {
|
||||
this(javaCs.newDecoder());
|
||||
}
|
||||
|
||||
protected Decoder (CharsetDecoder dec) {
|
||||
super(awtCs,
|
||||
dec.averageCharsPerByte(),
|
||||
dec.maxCharsPerByte());
|
||||
this.dec = dec;
|
||||
}
|
||||
protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
|
||||
return dec.decode(src, dst, true);
|
||||
}
|
||||
ByteBuffer fbb = ByteBuffer.allocate(0);
|
||||
protected CoderResult implFlush(CharBuffer out) {
|
||||
dec.decode(fbb, out, true);
|
||||
return dec.flush(out);
|
||||
}
|
||||
protected void implReset() {
|
||||
dec.reset();
|
||||
}
|
||||
protected void implReplaceWith(String newReplacement) {
|
||||
if (dec != null)
|
||||
dec.replaceWith(newReplacement);
|
||||
}
|
||||
protected void implOnMalformedInput(CodingErrorAction newAction) {
|
||||
dec.onMalformedInput(newAction);
|
||||
}
|
||||
protected void implOnUnmappableCharacter(CodingErrorAction newAction) {
|
||||
dec.onUnmappableCharacter(newAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
42
jdkSrc/jdk8/sun/awt/AWTPermissionFactory.java
Normal file
42
jdkSrc/jdk8/sun/awt/AWTPermissionFactory.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 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;
|
||||
|
||||
import java.awt.AWTPermission;
|
||||
import sun.security.util.PermissionFactory;
|
||||
|
||||
/**
|
||||
* A factory object for AWTPermission objects.
|
||||
*/
|
||||
|
||||
public class AWTPermissionFactory
|
||||
implements PermissionFactory<AWTPermission>
|
||||
{
|
||||
@Override
|
||||
public AWTPermission newPermission(String name) {
|
||||
return new AWTPermission(name);
|
||||
}
|
||||
}
|
||||
65
jdkSrc/jdk8/sun/awt/AWTSecurityManager.java
Normal file
65
jdkSrc/jdk8/sun/awt/AWTSecurityManager.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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;
|
||||
|
||||
/**
|
||||
* The AWTSecurityManager class provides the ability to secondarily
|
||||
* index AppContext objects through SecurityManager extensions.
|
||||
* As noted in AppContext.java, AppContexts are primarily indexed by
|
||||
* ThreadGroup. In the case where the ThreadGroup doesn't provide
|
||||
* enough information to determine AppContext (e.g. system threads),
|
||||
* if a SecurityManager is installed which derives from
|
||||
* AWTSecurityManager, the AWTSecurityManager's getAppContext()
|
||||
* method is called to determine the AppContext.
|
||||
*
|
||||
* A typical example of the use of this class is where an applet
|
||||
* is called by a system thread, yet the system AppContext is
|
||||
* inappropriate, because applet code is currently executing.
|
||||
* In this case, the getAppContext() method can walk the call stack
|
||||
* to determine the applet code being executed and return the applet's
|
||||
* AppContext object.
|
||||
*
|
||||
* @author Fred Ecks
|
||||
*/
|
||||
public class AWTSecurityManager extends SecurityManager {
|
||||
|
||||
/**
|
||||
* Get the AppContext corresponding to the current context.
|
||||
* The default implementation returns null, but this method
|
||||
* may be overridden by various SecurityManagers
|
||||
* (e.g. AppletSecurity) to index AppContext objects by the
|
||||
* calling context.
|
||||
*
|
||||
* @return the AppContext corresponding to the current context.
|
||||
* @see sun.awt.AppContext
|
||||
* @see java.lang.SecurityManager
|
||||
* @since JDK1.2.1
|
||||
*/
|
||||
public AppContext getAppContext() {
|
||||
return null; // Default implementation returns null
|
||||
}
|
||||
|
||||
} /* class AWTSecurityManager */
|
||||
932
jdkSrc/jdk8/sun/awt/AppContext.java
Normal file
932
jdkSrc/jdk8/sun/awt/AppContext.java
Normal file
@@ -0,0 +1,932 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, 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;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Window;
|
||||
import java.awt.SystemTray;
|
||||
import java.awt.TrayIcon;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.event.InvocationEvent;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.ref.SoftReference;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* The AppContext is a table referenced by ThreadGroup which stores
|
||||
* application service instances. (If you are not writing an application
|
||||
* service, or don't know what one is, please do not use this class.)
|
||||
* The AppContext allows applet access to what would otherwise be
|
||||
* potentially dangerous services, such as the ability to peek at
|
||||
* EventQueues or change the look-and-feel of a Swing application.<p>
|
||||
*
|
||||
* Most application services use a singleton object to provide their
|
||||
* services, either as a default (such as getSystemEventQueue or
|
||||
* getDefaultToolkit) or as static methods with class data (System).
|
||||
* The AppContext works with the former method by extending the concept
|
||||
* of "default" to be ThreadGroup-specific. Application services
|
||||
* lookup their singleton in the AppContext.<p>
|
||||
*
|
||||
* For example, here we have a Foo service, with its pre-AppContext
|
||||
* code:<p>
|
||||
* <code><pre>
|
||||
* public class Foo {
|
||||
* private static Foo defaultFoo = new Foo();
|
||||
*
|
||||
* public static Foo getDefaultFoo() {
|
||||
* return defaultFoo;
|
||||
* }
|
||||
*
|
||||
* ... Foo service methods
|
||||
* }</pre></code><p>
|
||||
*
|
||||
* The problem with the above is that the Foo service is global in scope,
|
||||
* so that applets and other untrusted code can execute methods on the
|
||||
* single, shared Foo instance. The Foo service therefore either needs
|
||||
* to block its use by untrusted code using a SecurityManager test, or
|
||||
* restrict its capabilities so that it doesn't matter if untrusted code
|
||||
* executes it.<p>
|
||||
*
|
||||
* Here's the Foo class written to use the AppContext:<p>
|
||||
* <code><pre>
|
||||
* public class Foo {
|
||||
* public static Foo getDefaultFoo() {
|
||||
* Foo foo = (Foo)AppContext.getAppContext().get(Foo.class);
|
||||
* if (foo == null) {
|
||||
* foo = new Foo();
|
||||
* getAppContext().put(Foo.class, foo);
|
||||
* }
|
||||
* return foo;
|
||||
* }
|
||||
*
|
||||
* ... Foo service methods
|
||||
* }</pre></code><p>
|
||||
*
|
||||
* Since a separate AppContext can exist for each ThreadGroup, trusted
|
||||
* and untrusted code have access to different Foo instances. This allows
|
||||
* untrusted code access to "system-wide" services -- the service remains
|
||||
* within the AppContext "sandbox". For example, say a malicious applet
|
||||
* wants to peek all of the key events on the EventQueue to listen for
|
||||
* passwords; if separate EventQueues are used for each ThreadGroup
|
||||
* using AppContexts, the only key events that applet will be able to
|
||||
* listen to are its own. A more reasonable applet request would be to
|
||||
* change the Swing default look-and-feel; with that default stored in
|
||||
* an AppContext, the applet's look-and-feel will change without
|
||||
* disrupting other applets or potentially the browser itself.<p>
|
||||
*
|
||||
* Because the AppContext is a facility for safely extending application
|
||||
* service support to applets, none of its methods may be blocked by a
|
||||
* a SecurityManager check in a valid Java implementation. Applets may
|
||||
* therefore safely invoke any of its methods without worry of being
|
||||
* blocked.
|
||||
*
|
||||
* Note: If a SecurityManager is installed which derives from
|
||||
* sun.awt.AWTSecurityManager, it may override the
|
||||
* AWTSecurityManager.getAppContext() method to return the proper
|
||||
* AppContext based on the execution context, in the case where
|
||||
* the default ThreadGroup-based AppContext indexing would return
|
||||
* the main "system" AppContext. For example, in an applet situation,
|
||||
* if a system thread calls into an applet, rather than returning the
|
||||
* main "system" AppContext (the one corresponding to the system thread),
|
||||
* an installed AWTSecurityManager may return the applet's AppContext
|
||||
* based on the execution context.
|
||||
*
|
||||
* @author Thomas Ball
|
||||
* @author Fred Ecks
|
||||
*/
|
||||
public final class AppContext {
|
||||
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.AppContext");
|
||||
|
||||
/* Since the contents of an AppContext are unique to each Java
|
||||
* session, this class should never be serialized. */
|
||||
|
||||
/*
|
||||
* The key to put()/get() the Java EventQueue into/from the AppContext.
|
||||
*/
|
||||
public static final Object EVENT_QUEUE_KEY = new StringBuffer("EventQueue");
|
||||
|
||||
/*
|
||||
* The keys to store EventQueue push/pop lock and condition.
|
||||
*/
|
||||
public final static Object EVENT_QUEUE_LOCK_KEY = new StringBuilder("EventQueue.Lock");
|
||||
public final static Object EVENT_QUEUE_COND_KEY = new StringBuilder("EventQueue.Condition");
|
||||
|
||||
/* A map of AppContexts, referenced by ThreadGroup.
|
||||
*/
|
||||
private static final Map<ThreadGroup, AppContext> threadGroup2appContext =
|
||||
Collections.synchronizedMap(new IdentityHashMap<ThreadGroup, AppContext>());
|
||||
|
||||
/**
|
||||
* Returns a set containing all <code>AppContext</code>s.
|
||||
*/
|
||||
public static Set<AppContext> getAppContexts() {
|
||||
synchronized (threadGroup2appContext) {
|
||||
return new HashSet<AppContext>(threadGroup2appContext.values());
|
||||
}
|
||||
}
|
||||
|
||||
/* The main "system" AppContext, used by everything not otherwise
|
||||
contained in another AppContext. It is implicitly created for
|
||||
standalone apps only (i.e. not applets)
|
||||
*/
|
||||
private static volatile AppContext mainAppContext = null;
|
||||
|
||||
private static class GetAppContextLock {};
|
||||
private final static Object getAppContextLock = new GetAppContextLock();
|
||||
|
||||
/*
|
||||
* The hash map associated with this AppContext. A private delegate
|
||||
* is used instead of subclassing HashMap so as to avoid all of
|
||||
* HashMap's potentially risky methods, such as clear(), elements(),
|
||||
* putAll(), etc.
|
||||
*/
|
||||
private final Map<Object, Object> table = new HashMap<>();
|
||||
|
||||
private final ThreadGroup threadGroup;
|
||||
|
||||
/**
|
||||
* If any <code>PropertyChangeListeners</code> have been registered,
|
||||
* the <code>changeSupport</code> field describes them.
|
||||
*
|
||||
* @see #addPropertyChangeListener
|
||||
* @see #removePropertyChangeListener
|
||||
* @see #firePropertyChange
|
||||
*/
|
||||
private PropertyChangeSupport changeSupport = null;
|
||||
|
||||
public static final String DISPOSED_PROPERTY_NAME = "disposed";
|
||||
public static final String GUI_DISPOSED = "guidisposed";
|
||||
|
||||
private enum State {
|
||||
VALID,
|
||||
BEING_DISPOSED,
|
||||
DISPOSED
|
||||
};
|
||||
|
||||
private volatile State state = State.VALID;
|
||||
|
||||
public boolean isDisposed() {
|
||||
return state == State.DISPOSED;
|
||||
}
|
||||
|
||||
/*
|
||||
* The total number of AppContexts, system-wide. This number is
|
||||
* incremented at the beginning of the constructor, and decremented
|
||||
* at the end of dispose(). getAppContext() checks to see if this
|
||||
* number is 1. If so, it returns the sole AppContext without
|
||||
* checking Thread.currentThread().
|
||||
*/
|
||||
private static final AtomicInteger numAppContexts = new AtomicInteger(0);
|
||||
|
||||
|
||||
/*
|
||||
* The context ClassLoader that was used to create this AppContext.
|
||||
*/
|
||||
private final ClassLoader contextClassLoader;
|
||||
|
||||
/**
|
||||
* Constructor for AppContext. This method is <i>not</i> public,
|
||||
* nor should it ever be used as such. The proper way to construct
|
||||
* an AppContext is through the use of SunToolkit.createNewAppContext.
|
||||
* A ThreadGroup is created for the new AppContext, a Thread is
|
||||
* created within that ThreadGroup, and that Thread calls
|
||||
* SunToolkit.createNewAppContext before calling anything else.
|
||||
* That creates both the new AppContext and its EventQueue.
|
||||
*
|
||||
* @param threadGroup The ThreadGroup for the new AppContext
|
||||
* @see sun.awt.SunToolkit
|
||||
* @since 1.2
|
||||
*/
|
||||
AppContext(ThreadGroup threadGroup) {
|
||||
numAppContexts.incrementAndGet();
|
||||
|
||||
this.threadGroup = threadGroup;
|
||||
threadGroup2appContext.put(threadGroup, this);
|
||||
|
||||
this.contextClassLoader =
|
||||
AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||
public ClassLoader run() {
|
||||
return Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize push/pop lock and its condition to be used by all the
|
||||
// EventQueues within this AppContext
|
||||
Lock eventQueuePushPopLock = new ReentrantLock();
|
||||
put(EVENT_QUEUE_LOCK_KEY, eventQueuePushPopLock);
|
||||
Condition eventQueuePushPopCond = eventQueuePushPopLock.newCondition();
|
||||
put(EVENT_QUEUE_COND_KEY, eventQueuePushPopCond);
|
||||
}
|
||||
|
||||
private static final ThreadLocal<AppContext> threadAppContext =
|
||||
new ThreadLocal<AppContext>();
|
||||
|
||||
private final static void initMainAppContext() {
|
||||
// On the main Thread, we get the ThreadGroup, make a corresponding
|
||||
// AppContext, and instantiate the Java EventQueue. This way, legacy
|
||||
// code is unaffected by the move to multiple AppContext ability.
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
ThreadGroup currentThreadGroup =
|
||||
Thread.currentThread().getThreadGroup();
|
||||
ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
|
||||
while (parentThreadGroup != null) {
|
||||
// Find the root ThreadGroup to construct our main AppContext
|
||||
currentThreadGroup = parentThreadGroup;
|
||||
parentThreadGroup = currentThreadGroup.getParent();
|
||||
}
|
||||
|
||||
mainAppContext = SunToolkit.createNewAppContext(currentThreadGroup);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate AppContext for the caller,
|
||||
* as determined by its ThreadGroup. If the main "system" AppContext
|
||||
* would be returned and there's an AWTSecurityManager installed, it
|
||||
* is called to get the proper AppContext based on the execution
|
||||
* context.
|
||||
*
|
||||
* @return the AppContext for the caller.
|
||||
* @see java.lang.ThreadGroup
|
||||
* @since 1.2
|
||||
*/
|
||||
public final static AppContext getAppContext() {
|
||||
// we are standalone app, return the main app context
|
||||
if (numAppContexts.get() == 1 && mainAppContext != null) {
|
||||
return mainAppContext;
|
||||
}
|
||||
|
||||
AppContext appContext = threadAppContext.get();
|
||||
|
||||
if (null == appContext) {
|
||||
appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
|
||||
{
|
||||
public AppContext run() {
|
||||
// Get the current ThreadGroup, and look for it and its
|
||||
// parents in the hash from ThreadGroup to AppContext --
|
||||
// it should be found, because we use createNewContext()
|
||||
// when new AppContext objects are created.
|
||||
ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
|
||||
ThreadGroup threadGroup = currentThreadGroup;
|
||||
|
||||
// Special case: we implicitly create the main app context
|
||||
// if no contexts have been created yet. This covers standalone apps
|
||||
// and excludes applets because by the time applet starts
|
||||
// a number of contexts have already been created by the plugin.
|
||||
synchronized (getAppContextLock) {
|
||||
if (numAppContexts.get() == 0) {
|
||||
if (System.getProperty("javaplugin.version") == null &&
|
||||
System.getProperty("javawebstart.version") == null) {
|
||||
initMainAppContext();
|
||||
} else if (System.getProperty("javafx.version") != null &&
|
||||
threadGroup.getParent() != null) {
|
||||
// Swing inside JavaFX case
|
||||
SunToolkit.createNewAppContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AppContext context = threadGroup2appContext.get(threadGroup);
|
||||
while (context == null) {
|
||||
threadGroup = threadGroup.getParent();
|
||||
if (threadGroup == null) {
|
||||
// We've got up to the root thread group and did not find an AppContext
|
||||
// Try to get it from the security manager
|
||||
SecurityManager securityManager = System.getSecurityManager();
|
||||
if (securityManager != null) {
|
||||
ThreadGroup smThreadGroup = securityManager.getThreadGroup();
|
||||
if (smThreadGroup != null) {
|
||||
/*
|
||||
* If we get this far then it's likely that
|
||||
* the ThreadGroup does not actually belong
|
||||
* to the applet, so do not cache it.
|
||||
*/
|
||||
return threadGroup2appContext.get(smThreadGroup);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
context = threadGroup2appContext.get(threadGroup);
|
||||
}
|
||||
|
||||
// In case we did anything in the above while loop, we add
|
||||
// all the intermediate ThreadGroups to threadGroup2appContext
|
||||
// so we won't spin again.
|
||||
for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
|
||||
threadGroup2appContext.put(tg, context);
|
||||
}
|
||||
|
||||
// Now we're done, so we cache the latest key/value pair.
|
||||
threadAppContext.set(context);
|
||||
|
||||
return context;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return appContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified AppContext is the main AppContext.
|
||||
*
|
||||
* @param ctx the context to compare with the main context
|
||||
* @return true if the specified AppContext is the main AppContext.
|
||||
* @since 1.8
|
||||
*/
|
||||
public final static boolean isMainContext(AppContext ctx) {
|
||||
return (ctx != null && ctx == mainAppContext);
|
||||
}
|
||||
|
||||
private final static AppContext getExecutionAppContext() {
|
||||
SecurityManager securityManager = System.getSecurityManager();
|
||||
if ((securityManager != null) &&
|
||||
(securityManager instanceof AWTSecurityManager))
|
||||
{
|
||||
AWTSecurityManager awtSecMgr = (AWTSecurityManager) securityManager;
|
||||
AppContext secAppContext = awtSecMgr.getAppContext();
|
||||
return secAppContext; // Return what we're told
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private long DISPOSAL_TIMEOUT = 5000; // Default to 5-second timeout
|
||||
// for disposal of all Frames
|
||||
// (we wait for this time twice,
|
||||
// once for dispose(), and once
|
||||
// to clear the EventQueue).
|
||||
|
||||
private long THREAD_INTERRUPT_TIMEOUT = 1000;
|
||||
// Default to 1-second timeout for all
|
||||
// interrupted Threads to exit, and another
|
||||
// 1 second for all stopped Threads to die.
|
||||
|
||||
/**
|
||||
* Disposes of this AppContext, all of its top-level Frames, and
|
||||
* all Threads and ThreadGroups contained within it.
|
||||
*
|
||||
* This method must be called from a Thread which is not contained
|
||||
* within this AppContext.
|
||||
*
|
||||
* @exception IllegalThreadStateException if the current thread is
|
||||
* contained within this AppContext
|
||||
* @since 1.2
|
||||
*/
|
||||
public void dispose() throws IllegalThreadStateException {
|
||||
// Check to be sure that the current Thread isn't in this AppContext
|
||||
if (this.threadGroup.parentOf(Thread.currentThread().getThreadGroup())) {
|
||||
throw new IllegalThreadStateException(
|
||||
"Current Thread is contained within AppContext to be disposed."
|
||||
);
|
||||
}
|
||||
|
||||
synchronized(this) {
|
||||
if (this.state != State.VALID) {
|
||||
return; // If already disposed or being disposed, bail.
|
||||
}
|
||||
|
||||
this.state = State.BEING_DISPOSED;
|
||||
}
|
||||
|
||||
final PropertyChangeSupport changeSupport = this.changeSupport;
|
||||
if (changeSupport != null) {
|
||||
changeSupport.firePropertyChange(DISPOSED_PROPERTY_NAME, false, true);
|
||||
}
|
||||
|
||||
// First, we post an InvocationEvent to be run on the
|
||||
// EventDispatchThread which disposes of all top-level Frames and TrayIcons
|
||||
|
||||
final Object notificationLock = new Object();
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
Window[] windowsToDispose = Window.getOwnerlessWindows();
|
||||
for (Window w : windowsToDispose) {
|
||||
try {
|
||||
w.dispose();
|
||||
} catch (Throwable t) {
|
||||
log.finer("exception occurred while disposing app context", t);
|
||||
}
|
||||
}
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
if (!GraphicsEnvironment.isHeadless() && SystemTray.isSupported())
|
||||
{
|
||||
SystemTray systemTray = SystemTray.getSystemTray();
|
||||
TrayIcon[] trayIconsToDispose = systemTray.getTrayIcons();
|
||||
for (TrayIcon ti : trayIconsToDispose) {
|
||||
systemTray.remove(ti);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
// Alert PropertyChangeListeners that the GUI has been disposed.
|
||||
if (changeSupport != null) {
|
||||
changeSupport.firePropertyChange(GUI_DISPOSED, false, true);
|
||||
}
|
||||
synchronized(notificationLock) {
|
||||
notificationLock.notifyAll(); // Notify caller that we're done
|
||||
}
|
||||
}
|
||||
};
|
||||
synchronized(notificationLock) {
|
||||
SunToolkit.postEvent(this,
|
||||
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
|
||||
try {
|
||||
notificationLock.wait(DISPOSAL_TIMEOUT);
|
||||
} catch (InterruptedException e) { }
|
||||
}
|
||||
|
||||
// Next, we post another InvocationEvent to the end of the
|
||||
// EventQueue. When it's executed, we know we've executed all
|
||||
// events in the queue.
|
||||
|
||||
runnable = new Runnable() { public void run() {
|
||||
synchronized(notificationLock) {
|
||||
notificationLock.notifyAll(); // Notify caller that we're done
|
||||
}
|
||||
} };
|
||||
synchronized(notificationLock) {
|
||||
SunToolkit.postEvent(this,
|
||||
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
|
||||
try {
|
||||
notificationLock.wait(DISPOSAL_TIMEOUT);
|
||||
} catch (InterruptedException e) { }
|
||||
}
|
||||
|
||||
// We are done with posting events, so change the state to disposed
|
||||
synchronized(this) {
|
||||
this.state = State.DISPOSED;
|
||||
}
|
||||
|
||||
// Next, we interrupt all Threads in the ThreadGroup
|
||||
this.threadGroup.interrupt();
|
||||
// Note, the EventDispatchThread we've interrupted may dump an
|
||||
// InterruptedException to the console here. This needs to be
|
||||
// fixed in the EventDispatchThread, not here.
|
||||
|
||||
// Next, we sleep 10ms at a time, waiting for all of the active
|
||||
// Threads in the ThreadGroup to exit.
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
long endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
|
||||
while ((this.threadGroup.activeCount() > 0) &&
|
||||
(System.currentTimeMillis() < endTime)) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) { }
|
||||
}
|
||||
|
||||
// Then, we stop any remaining Threads
|
||||
this.threadGroup.stop();
|
||||
|
||||
// Next, we sleep 10ms at a time, waiting for all of the active
|
||||
// Threads in the ThreadGroup to die.
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
|
||||
while ((this.threadGroup.activeCount() > 0) &&
|
||||
(System.currentTimeMillis() < endTime)) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) { }
|
||||
}
|
||||
|
||||
// Next, we remove this and all subThreadGroups from threadGroup2appContext
|
||||
int numSubGroups = this.threadGroup.activeGroupCount();
|
||||
if (numSubGroups > 0) {
|
||||
ThreadGroup [] subGroups = new ThreadGroup[numSubGroups];
|
||||
numSubGroups = this.threadGroup.enumerate(subGroups);
|
||||
for (int subGroup = 0; subGroup < numSubGroups; subGroup++) {
|
||||
threadGroup2appContext.remove(subGroups[subGroup]);
|
||||
}
|
||||
}
|
||||
threadGroup2appContext.remove(this.threadGroup);
|
||||
|
||||
threadAppContext.set(null);
|
||||
|
||||
// Finally, we destroy the ThreadGroup entirely.
|
||||
try {
|
||||
this.threadGroup.destroy();
|
||||
} catch (IllegalThreadStateException e) {
|
||||
// Fired if not all the Threads died, ignore it and proceed
|
||||
}
|
||||
|
||||
synchronized (table) {
|
||||
this.table.clear(); // Clear out the Hashtable to ease garbage collection
|
||||
}
|
||||
|
||||
numAppContexts.decrementAndGet();
|
||||
|
||||
mostRecentKeyValue = null;
|
||||
}
|
||||
|
||||
static final class PostShutdownEventRunnable implements Runnable {
|
||||
private final AppContext appContext;
|
||||
|
||||
public PostShutdownEventRunnable(AppContext ac) {
|
||||
appContext = ac;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
final EventQueue eq = (EventQueue)appContext.get(EVENT_QUEUE_KEY);
|
||||
if (eq != null) {
|
||||
eq.postEvent(AWTAutoShutdown.getShutdownEvent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class CreateThreadAction implements PrivilegedAction<Thread> {
|
||||
private final AppContext appContext;
|
||||
private final Runnable runnable;
|
||||
|
||||
public CreateThreadAction(AppContext ac, Runnable r) {
|
||||
appContext = ac;
|
||||
runnable = r;
|
||||
}
|
||||
|
||||
public Thread run() {
|
||||
Thread t = new Thread(appContext.getThreadGroup(), runnable);
|
||||
t.setContextClassLoader(appContext.getContextClassLoader());
|
||||
t.setPriority(Thread.NORM_PRIORITY + 1);
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
static void stopEventDispatchThreads() {
|
||||
for (AppContext appContext: getAppContexts()) {
|
||||
if (appContext.isDisposed()) {
|
||||
continue;
|
||||
}
|
||||
Runnable r = new PostShutdownEventRunnable(appContext);
|
||||
// For security reasons EventQueue.postEvent should only be called
|
||||
// on a thread that belongs to the corresponding thread group.
|
||||
if (appContext != AppContext.getAppContext()) {
|
||||
// Create a thread that belongs to the thread group associated
|
||||
// with the AppContext and invokes EventQueue.postEvent.
|
||||
PrivilegedAction<Thread> action = new CreateThreadAction(appContext, r);
|
||||
Thread thread = AccessController.doPrivileged(action);
|
||||
thread.start();
|
||||
} else {
|
||||
r.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MostRecentKeyValue mostRecentKeyValue = null;
|
||||
private MostRecentKeyValue shadowMostRecentKeyValue = null;
|
||||
|
||||
/**
|
||||
* Returns the value to which the specified key is mapped in this context.
|
||||
*
|
||||
* @param key a key in the AppContext.
|
||||
* @return the value to which the key is mapped in this AppContext;
|
||||
* <code>null</code> if the key is not mapped to any value.
|
||||
* @see #put(Object, Object)
|
||||
* @since 1.2
|
||||
*/
|
||||
public Object get(Object key) {
|
||||
/*
|
||||
* The most recent reference should be updated inside a synchronized
|
||||
* block to avoid a race when put() and get() are executed in
|
||||
* parallel on different threads.
|
||||
*/
|
||||
synchronized (table) {
|
||||
// Note: this most recent key/value caching is thread-hot.
|
||||
// A simple test using SwingSet found that 72% of lookups
|
||||
// were matched using the most recent key/value. By instantiating
|
||||
// a simple MostRecentKeyValue object on cache misses, the
|
||||
// cache hits can be processed without synchronization.
|
||||
|
||||
MostRecentKeyValue recent = mostRecentKeyValue;
|
||||
if ((recent != null) && (recent.key == key)) {
|
||||
return recent.value;
|
||||
}
|
||||
|
||||
Object value = table.get(key);
|
||||
if(mostRecentKeyValue == null) {
|
||||
mostRecentKeyValue = new MostRecentKeyValue(key, value);
|
||||
shadowMostRecentKeyValue = new MostRecentKeyValue(key, value);
|
||||
} else {
|
||||
MostRecentKeyValue auxKeyValue = mostRecentKeyValue;
|
||||
shadowMostRecentKeyValue.setPair(key, value);
|
||||
mostRecentKeyValue = shadowMostRecentKeyValue;
|
||||
shadowMostRecentKeyValue = auxKeyValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the specified <code>key</code> to the specified
|
||||
* <code>value</code> in this AppContext. Neither the key nor the
|
||||
* value can be <code>null</code>.
|
||||
* <p>
|
||||
* The value can be retrieved by calling the <code>get</code> method
|
||||
* with a key that is equal to the original key.
|
||||
*
|
||||
* @param key the AppContext key.
|
||||
* @param value the value.
|
||||
* @return the previous value of the specified key in this
|
||||
* AppContext, or <code>null</code> if it did not have one.
|
||||
* @exception NullPointerException if the key or value is
|
||||
* <code>null</code>.
|
||||
* @see #get(Object)
|
||||
* @since 1.2
|
||||
*/
|
||||
public Object put(Object key, Object value) {
|
||||
synchronized (table) {
|
||||
MostRecentKeyValue recent = mostRecentKeyValue;
|
||||
if ((recent != null) && (recent.key == key))
|
||||
recent.value = value;
|
||||
return table.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the key (and its corresponding value) from this
|
||||
* AppContext. This method does nothing if the key is not in the
|
||||
* AppContext.
|
||||
*
|
||||
* @param key the key that needs to be removed.
|
||||
* @return the value to which the key had been mapped in this AppContext,
|
||||
* or <code>null</code> if the key did not have a mapping.
|
||||
* @since 1.2
|
||||
*/
|
||||
public Object remove(Object key) {
|
||||
synchronized (table) {
|
||||
MostRecentKeyValue recent = mostRecentKeyValue;
|
||||
if ((recent != null) && (recent.key == key))
|
||||
recent.value = null;
|
||||
return table.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root ThreadGroup for all Threads contained within
|
||||
* this AppContext.
|
||||
* @since 1.2
|
||||
*/
|
||||
public ThreadGroup getThreadGroup() {
|
||||
return threadGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the context ClassLoader that was used to create this
|
||||
* AppContext.
|
||||
*
|
||||
* @see java.lang.Thread#getContextClassLoader
|
||||
*/
|
||||
public ClassLoader getContextClassLoader() {
|
||||
return contextClassLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this AppContext.
|
||||
* @since 1.2
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the property change listeners
|
||||
* registered on this component.
|
||||
*
|
||||
* @return all of this component's <code>PropertyChangeListener</code>s
|
||||
* or an empty array if no property change
|
||||
* listeners are currently registered
|
||||
*
|
||||
* @see #addPropertyChangeListener
|
||||
* @see #removePropertyChangeListener
|
||||
* @see #getPropertyChangeListeners(java.lang.String)
|
||||
* @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
|
||||
if (changeSupport == null) {
|
||||
return new PropertyChangeListener[0];
|
||||
}
|
||||
return changeSupport.getPropertyChangeListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a PropertyChangeListener to the listener list for a specific
|
||||
* property. The specified property may be one of the following:
|
||||
* <ul>
|
||||
* <li>if this AppContext is disposed ("disposed")</li>
|
||||
* </ul>
|
||||
* <ul>
|
||||
* <li>if this AppContext's unowned Windows have been disposed
|
||||
* ("guidisposed"). Code to cleanup after the GUI is disposed
|
||||
* (such as LookAndFeel.uninitialize()) should execute in response to
|
||||
* this property being fired. Notifications for the "guidisposed"
|
||||
* property are sent on the event dispatch thread.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* If listener is null, no exception is thrown and no action is performed.
|
||||
*
|
||||
* @param propertyName one of the property names listed above
|
||||
* @param listener the PropertyChangeListener to be added
|
||||
*
|
||||
* @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
||||
* @see #getPropertyChangeListeners(java.lang.String)
|
||||
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
||||
*/
|
||||
public synchronized void addPropertyChangeListener(
|
||||
String propertyName,
|
||||
PropertyChangeListener listener) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
if (changeSupport == null) {
|
||||
changeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
changeSupport.addPropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a PropertyChangeListener from the listener list for a specific
|
||||
* property. This method should be used to remove PropertyChangeListeners
|
||||
* that were registered for a specific bound property.
|
||||
* <p>
|
||||
* If listener is null, no exception is thrown and no action is performed.
|
||||
*
|
||||
* @param propertyName a valid property name
|
||||
* @param listener the PropertyChangeListener to be removed
|
||||
*
|
||||
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
||||
* @see #getPropertyChangeListeners(java.lang.String)
|
||||
* @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
|
||||
*/
|
||||
public synchronized void removePropertyChangeListener(
|
||||
String propertyName,
|
||||
PropertyChangeListener listener) {
|
||||
if (listener == null || changeSupport == null) {
|
||||
return;
|
||||
}
|
||||
changeSupport.removePropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the listeners which have been associated
|
||||
* with the named property.
|
||||
*
|
||||
* @return all of the <code>PropertyChangeListeners</code> associated with
|
||||
* the named property or an empty array if no listeners have
|
||||
* been added
|
||||
*
|
||||
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
||||
* @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
||||
* @see #getPropertyChangeListeners
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized PropertyChangeListener[] getPropertyChangeListeners(
|
||||
String propertyName) {
|
||||
if (changeSupport == null) {
|
||||
return new PropertyChangeListener[0];
|
||||
}
|
||||
return changeSupport.getPropertyChangeListeners(propertyName);
|
||||
}
|
||||
|
||||
// Set up JavaAWTAccess in SharedSecrets
|
||||
static {
|
||||
sun.misc.SharedSecrets.setJavaAWTAccess(new sun.misc.JavaAWTAccess() {
|
||||
private boolean hasRootThreadGroup(final AppContext ecx) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean run() {
|
||||
return ecx.threadGroup.getParent() == null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the AppContext used for applet logging isolation, or null if
|
||||
* the default global context can be used.
|
||||
* If there's no applet, or if the caller is a stand alone application,
|
||||
* or running in the main app context, returns null.
|
||||
* Otherwise, returns the AppContext of the calling applet.
|
||||
* @return null if the global default context can be used,
|
||||
* an AppContext otherwise.
|
||||
**/
|
||||
public Object getAppletContext() {
|
||||
// There's no AppContext: return null.
|
||||
// No need to call getAppContext() if numAppContext == 0:
|
||||
// it means that no AppContext has been created yet, and
|
||||
// we don't want to trigger the creation of a main app
|
||||
// context since we don't need it.
|
||||
if (numAppContexts.get() == 0) return null;
|
||||
|
||||
// Get the context from the security manager
|
||||
AppContext ecx = getExecutionAppContext();
|
||||
|
||||
// Not sure we really need to re-check numAppContexts here.
|
||||
// If all applets have gone away then we could have a
|
||||
// numAppContexts coming back to 0. So we recheck
|
||||
// it here because we don't want to trigger the
|
||||
// creation of a main AppContext in that case.
|
||||
// This is probably not 100% MT-safe but should reduce
|
||||
// the window of opportunity in which that issue could
|
||||
// happen.
|
||||
if (numAppContexts.get() > 0) {
|
||||
// Defaults to thread group caching.
|
||||
// This is probably not required as we only really need
|
||||
// isolation in a deployed applet environment, in which
|
||||
// case ecx will not be null when we reach here
|
||||
// However it helps emulate the deployed environment,
|
||||
// in tests for instance.
|
||||
ecx = ecx != null ? ecx : getAppContext();
|
||||
}
|
||||
|
||||
// getAppletContext() may be called when initializing the main
|
||||
// app context - in which case mainAppContext will still be
|
||||
// null. To work around this issue we simply use
|
||||
// AppContext.threadGroup.getParent() == null instead, since
|
||||
// mainAppContext is the only AppContext which should have
|
||||
// the root TG as its thread group.
|
||||
// See: JDK-8023258
|
||||
final boolean isMainAppContext = ecx == null
|
||||
|| mainAppContext == ecx
|
||||
|| mainAppContext == null && hasRootThreadGroup(ecx);
|
||||
|
||||
return isMainAppContext ? null : ecx;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> T getSoftReferenceValue(Object key,
|
||||
Supplier<T> supplier) {
|
||||
|
||||
final AppContext appContext = AppContext.getAppContext();
|
||||
SoftReference<T> ref = (SoftReference<T>) appContext.get(key);
|
||||
if (ref != null) {
|
||||
final T object = ref.get();
|
||||
if (object != null) {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
final T object = supplier.get();
|
||||
ref = new SoftReference<>(object);
|
||||
appContext.put(key, ref);
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
final class MostRecentKeyValue {
|
||||
Object key;
|
||||
Object value;
|
||||
MostRecentKeyValue(Object k, Object v) {
|
||||
key = k;
|
||||
value = v;
|
||||
}
|
||||
void setPair(Object k, Object v) {
|
||||
key = k;
|
||||
value = v;
|
||||
}
|
||||
}
|
||||
89
jdkSrc/jdk8/sun/awt/CausedFocusEvent.java
Normal file
89
jdkSrc/jdk8/sun/awt/CausedFocusEvent.java
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, 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;
|
||||
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.Component;
|
||||
|
||||
/**
|
||||
* This class represents FocusEvents with a known "cause" - reason why this event happened. It can
|
||||
* be mouse press, traversal, activation, and so on - all causes are described as Cause enum. The
|
||||
* event with the cause can be constructed in two ways - explicitly through constructor of
|
||||
* CausedFocusEvent class or implicitly, by calling appropriate requestFocusXXX method with "cause"
|
||||
* parameter. The default cause is UNKNOWN.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class CausedFocusEvent extends FocusEvent {
|
||||
public enum Cause {
|
||||
UNKNOWN,
|
||||
MOUSE_EVENT,
|
||||
TRAVERSAL,
|
||||
TRAVERSAL_UP,
|
||||
TRAVERSAL_DOWN,
|
||||
TRAVERSAL_FORWARD,
|
||||
TRAVERSAL_BACKWARD,
|
||||
MANUAL_REQUEST,
|
||||
AUTOMATIC_TRAVERSE,
|
||||
ROLLBACK,
|
||||
NATIVE_SYSTEM,
|
||||
ACTIVATION,
|
||||
CLEAR_GLOBAL_FOCUS_OWNER,
|
||||
RETARGETED
|
||||
};
|
||||
|
||||
private final Cause cause;
|
||||
|
||||
public Cause getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "java.awt.FocusEvent[" + super.paramString() + ",cause=" + cause + "] on " + getSource();
|
||||
}
|
||||
|
||||
public CausedFocusEvent(Component source, int id, boolean temporary,
|
||||
Component opposite, Cause cause) {
|
||||
super(source, id, temporary, opposite);
|
||||
if (cause == null) {
|
||||
cause = Cause.UNKNOWN;
|
||||
}
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retargets the original focus event to the new target. If the
|
||||
* original focus event is CausedFocusEvent, it remains such and
|
||||
* cause is copied. Otherwise, new CausedFocusEvent is created,
|
||||
* with cause as RETARGETED.
|
||||
* @return retargeted event, or null if e is null
|
||||
*/
|
||||
public static FocusEvent retarget(FocusEvent e, Component newSource) {
|
||||
if (e == null) return null;
|
||||
|
||||
return new CausedFocusEvent(newSource, e.getID(), e.isTemporary(), e.getOppositeComponent(),
|
||||
(e instanceof CausedFocusEvent) ? ((CausedFocusEvent)e).getCause() : Cause.RETARGETED);
|
||||
}
|
||||
}
|
||||
59
jdkSrc/jdk8/sun/awt/CharsetString.java
Normal file
59
jdkSrc/jdk8/sun/awt/CharsetString.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2012, 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;
|
||||
|
||||
public class CharsetString {
|
||||
/**
|
||||
* chars for this string. See also offset, length.
|
||||
*/
|
||||
public char[] charsetChars;
|
||||
|
||||
/**
|
||||
* Offset within charsetChars of first character
|
||||
**/
|
||||
public int offset;
|
||||
|
||||
/**
|
||||
* Length of the string we represent.
|
||||
**/
|
||||
public int length;
|
||||
|
||||
/**
|
||||
* This string's FontDescriptor.
|
||||
*/
|
||||
public FontDescriptor fontDescriptor;
|
||||
|
||||
/**
|
||||
* Creates a new CharsetString
|
||||
*/
|
||||
public CharsetString(char charsetChars[], int offset, int length,
|
||||
FontDescriptor fontDescriptor){
|
||||
|
||||
this.charsetChars = charsetChars;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
this.fontDescriptor = fontDescriptor;
|
||||
}
|
||||
}
|
||||
100
jdkSrc/jdk8/sun/awt/ComponentFactory.java
Normal file
100
jdkSrc/jdk8/sun/awt/ComponentFactory.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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;
|
||||
|
||||
import sun.awt.datatransfer.DataTransferer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.dnd.*;
|
||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||
import java.awt.peer.*;
|
||||
|
||||
/**
|
||||
* Interface for component creation support in toolkits
|
||||
*/
|
||||
public interface ComponentFactory {
|
||||
|
||||
CanvasPeer createCanvas(Canvas target) throws HeadlessException;
|
||||
|
||||
PanelPeer createPanel(Panel target) throws HeadlessException;
|
||||
|
||||
WindowPeer createWindow(Window target) throws HeadlessException;
|
||||
|
||||
FramePeer createFrame(Frame target) throws HeadlessException;
|
||||
|
||||
DialogPeer createDialog(Dialog target) throws HeadlessException;
|
||||
|
||||
ButtonPeer createButton(Button target) throws HeadlessException;
|
||||
|
||||
TextFieldPeer createTextField(TextField target)
|
||||
throws HeadlessException;
|
||||
|
||||
ChoicePeer createChoice(Choice target) throws HeadlessException;
|
||||
|
||||
LabelPeer createLabel(Label target) throws HeadlessException;
|
||||
|
||||
ListPeer createList(List target) throws HeadlessException;
|
||||
|
||||
CheckboxPeer createCheckbox(Checkbox target)
|
||||
throws HeadlessException;
|
||||
|
||||
ScrollbarPeer createScrollbar(Scrollbar target)
|
||||
throws HeadlessException;
|
||||
|
||||
ScrollPanePeer createScrollPane(ScrollPane target)
|
||||
throws HeadlessException;
|
||||
|
||||
TextAreaPeer createTextArea(TextArea target)
|
||||
throws HeadlessException;
|
||||
|
||||
FileDialogPeer createFileDialog(FileDialog target)
|
||||
throws HeadlessException;
|
||||
|
||||
MenuBarPeer createMenuBar(MenuBar target) throws HeadlessException;
|
||||
|
||||
MenuPeer createMenu(Menu target) throws HeadlessException;
|
||||
|
||||
PopupMenuPeer createPopupMenu(PopupMenu target)
|
||||
throws HeadlessException;
|
||||
|
||||
MenuItemPeer createMenuItem(MenuItem target)
|
||||
throws HeadlessException;
|
||||
|
||||
CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target)
|
||||
throws HeadlessException;
|
||||
|
||||
DragSourceContextPeer createDragSourceContextPeer(
|
||||
DragGestureEvent dge)
|
||||
throws InvalidDnDOperationException, HeadlessException;
|
||||
|
||||
FontPeer getFontPeer(String name, int style);
|
||||
|
||||
RobotPeer createRobot(Robot target, GraphicsDevice screen)
|
||||
throws AWTException, HeadlessException;
|
||||
|
||||
DataTransferer getDataTransferer();
|
||||
|
||||
}
|
||||
52
jdkSrc/jdk8/sun/awt/ConstrainableGraphics.java
Normal file
52
jdkSrc/jdk8/sun/awt/ConstrainableGraphics.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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;
|
||||
|
||||
/**
|
||||
* This interface can be implemented on a Graphics object to allow
|
||||
* the lightweight component code to permanently install a rectangular
|
||||
* maximum clip that cannot be extended with setClip and which works in
|
||||
* conjunction with the hit() and getTransform() methods of Graphics2D
|
||||
* to make it appear as if there really was a component with these
|
||||
* dimensions.
|
||||
*/
|
||||
public interface ConstrainableGraphics {
|
||||
/**
|
||||
* Constrain this graphics object to have a permanent device space
|
||||
* origin of (x, y) and a permanent maximum clip of (x,y,w,h).
|
||||
* Calling this method is roughly equivalent to:
|
||||
* g.translate(x, y);
|
||||
* g.clipRect(0, 0, w, h);
|
||||
* except that the clip can never be extended outside of these
|
||||
* bounds, even with setClip() and for the fact that the (x,y)
|
||||
* become a new device space coordinate origin.
|
||||
*
|
||||
* These methods are recursive so that you can further restrict
|
||||
* the object by calling the constrain() method more times, but
|
||||
* you can never enlarge its restricted maximum clip.
|
||||
*/
|
||||
public void constrain(int x, int y, int w, int h);
|
||||
}
|
||||
104
jdkSrc/jdk8/sun/awt/CustomCursor.java
Normal file
104
jdkSrc/jdk8/sun/awt/CustomCursor.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1999, 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;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* A class to encapsulate a custom image-based cursor.
|
||||
*
|
||||
* @author ThomasBall
|
||||
*/
|
||||
public abstract class CustomCursor extends Cursor {
|
||||
|
||||
protected Image image;
|
||||
|
||||
public CustomCursor(Image cursor, Point hotSpot, String name)
|
||||
throws IndexOutOfBoundsException {
|
||||
super(name);
|
||||
image = cursor;
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
|
||||
// Make sure image is fully loaded.
|
||||
Component c = new Canvas(); // for its imageUpdate method
|
||||
MediaTracker tracker = new MediaTracker(c);
|
||||
tracker.addImage(cursor, 0);
|
||||
try {
|
||||
tracker.waitForAll();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
int width = cursor.getWidth(c);
|
||||
int height = cursor.getHeight(c);
|
||||
|
||||
// Fix for bug 4212593 The Toolkit.createCustomCursor does not
|
||||
// check absence of the image of cursor
|
||||
// If the image is invalid, the cursor will be hidden (made completely
|
||||
// transparent). In this case, getBestCursorSize() will adjust negative w and h,
|
||||
// but we need to set the hotspot inside the image here.
|
||||
if (tracker.isErrorAny() || width < 0 || height < 0) {
|
||||
hotSpot.x = hotSpot.y = 0;
|
||||
}
|
||||
|
||||
// Scale image to nearest supported size.
|
||||
Dimension nativeSize = toolkit.getBestCursorSize(width, height);
|
||||
if ((nativeSize.width != width || nativeSize.height != height) &&
|
||||
(nativeSize.width != 0 && nativeSize.height != 0)) {
|
||||
cursor = cursor.getScaledInstance(nativeSize.width,
|
||||
nativeSize.height,
|
||||
Image.SCALE_DEFAULT);
|
||||
width = nativeSize.width;
|
||||
height = nativeSize.height;
|
||||
}
|
||||
|
||||
// Verify that the hotspot is within cursor bounds.
|
||||
if (hotSpot.x >= width || hotSpot.y >= height || hotSpot.x < 0 || hotSpot.y < 0) {
|
||||
throw new IndexOutOfBoundsException("invalid hotSpot");
|
||||
}
|
||||
|
||||
/* Extract ARGB array from image.
|
||||
*
|
||||
* A transparency mask can be created in native code by checking
|
||||
* each pixel's top byte -- a 0 value means the pixel's transparent.
|
||||
* Since each platform's format of the bitmap and mask are likely to
|
||||
* be different, their creation shouldn't be here.
|
||||
*/
|
||||
int[] pixels = new int[width * height];
|
||||
ImageProducer ip = cursor.getSource();
|
||||
PixelGrabber pg = new PixelGrabber(ip, 0, 0, width, height,
|
||||
pixels, 0, width);
|
||||
try {
|
||||
pg.grabPixels();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
createNativeCursor(image, pixels, width, height, hotSpot.x, hotSpot.y);
|
||||
}
|
||||
|
||||
protected abstract void createNativeCursor(Image im, int[] pixels,
|
||||
int width, int height,
|
||||
int xHotSpot, int yHotSpot);
|
||||
}
|
||||
311
jdkSrc/jdk8/sun/awt/DebugSettings.java
Normal file
311
jdkSrc/jdk8/sun/awt/DebugSettings.java
Normal file
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, 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;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import java.util.*;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
/*
|
||||
* Internal class that manages sun.awt.Debug settings.
|
||||
* Settings can be specified on a global, per-package,
|
||||
* or per-class level.
|
||||
*
|
||||
* Properties affecting the behaviour of the Debug class are
|
||||
* loaded from the awtdebug.properties file at class load
|
||||
* time. The properties file is assumed to be in the
|
||||
* user.home directory. A different file can be used
|
||||
* by setting the awtdebug.properties system property.
|
||||
* e.g. java -Dawtdebug.properties=foo.properties
|
||||
*
|
||||
* Only properties beginning with 'awtdebug' have any
|
||||
* meaning-- all other properties are ignored.
|
||||
*
|
||||
* You can override the properties file by specifying
|
||||
* 'awtdebug' props as system properties on the command line.
|
||||
* e.g. java -Dawtdebug.trace=true
|
||||
* Properties specific to a package or a class can be set
|
||||
* by qualifying the property names as follows:
|
||||
* awtdebug.<property name>.<class or package name>
|
||||
* So for example, turning on tracing in the com.acme.Fubar
|
||||
* class would be done as follows:
|
||||
* awtdebug.trace.com.acme.Fubar=true
|
||||
*
|
||||
* Class settings always override package settings, which in
|
||||
* turn override global settings.
|
||||
*
|
||||
* Addition from July, 2007.
|
||||
*
|
||||
* After the fix for 4638447 all the usage of DebugHelper
|
||||
* classes in Java code are replaced with the corresponding
|
||||
* Java Logging API calls. This file is now used only to
|
||||
* control native logging.
|
||||
*
|
||||
* To enable native logging you should set the following
|
||||
* system property to 'true': sun.awt.nativedebug. After
|
||||
* the native logging is enabled, the actual debug settings
|
||||
* are read the same way as described above (as before
|
||||
* the fix for 4638447).
|
||||
*/
|
||||
final class DebugSettings {
|
||||
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.debug.DebugSettings");
|
||||
|
||||
/* standard debug property key names */
|
||||
static final String PREFIX = "awtdebug";
|
||||
static final String PROP_FILE = "properties";
|
||||
|
||||
/* default property settings */
|
||||
private static final String DEFAULT_PROPS[] = {
|
||||
"awtdebug.assert=true",
|
||||
"awtdebug.trace=false",
|
||||
"awtdebug.on=true",
|
||||
"awtdebug.ctrace=false"
|
||||
};
|
||||
|
||||
/* global instance of the settings object */
|
||||
private static DebugSettings instance = null;
|
||||
|
||||
private Properties props = new Properties();
|
||||
|
||||
static void init() {
|
||||
if (instance != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
NativeLibLoader.loadLibraries();
|
||||
instance = new DebugSettings();
|
||||
instance.loadNativeSettings();
|
||||
}
|
||||
|
||||
private DebugSettings() {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
loadProperties();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Load debug properties from file, then override
|
||||
* with any command line specified properties
|
||||
*/
|
||||
private synchronized void loadProperties() {
|
||||
// setup initial properties
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
loadDefaultProperties();
|
||||
loadFileProperties();
|
||||
loadSystemProperties();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// echo the initial property settings to stdout
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
log.fine("DebugSettings:\n{0}", this);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
PrintStream pout = new PrintStream(bout);
|
||||
for (String key : props.stringPropertyNames()) {
|
||||
String value = props.getProperty(key, "");
|
||||
pout.println(key + " = " + value);
|
||||
}
|
||||
return new String(bout.toByteArray());
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets up default property values
|
||||
*/
|
||||
private void loadDefaultProperties() {
|
||||
// is there a more inefficient way to setup default properties?
|
||||
// maybe, but this has got to be close to 100% non-optimal
|
||||
try {
|
||||
for ( int nprop = 0; nprop < DEFAULT_PROPS.length; nprop++ ) {
|
||||
StringBufferInputStream in = new StringBufferInputStream(DEFAULT_PROPS[nprop]);
|
||||
props.load(in);
|
||||
in.close();
|
||||
}
|
||||
} catch(IOException ioe) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* load properties from file, overriding defaults
|
||||
*/
|
||||
private void loadFileProperties() {
|
||||
String propPath;
|
||||
Properties fileProps;
|
||||
|
||||
// check if the user specified a particular settings file
|
||||
propPath = System.getProperty(PREFIX + "." + PROP_FILE, "");
|
||||
if (propPath.equals("")) {
|
||||
// otherwise get it from the user's home directory
|
||||
propPath = System.getProperty("user.home", "") +
|
||||
File.separator +
|
||||
PREFIX + "." + PROP_FILE;
|
||||
}
|
||||
|
||||
File propFile = new File(propPath);
|
||||
try {
|
||||
println("Reading debug settings from '" + propFile.getCanonicalPath() + "'...");
|
||||
FileInputStream fin = new FileInputStream(propFile);
|
||||
props.load(fin);
|
||||
fin.close();
|
||||
} catch ( FileNotFoundException fne ) {
|
||||
println("Did not find settings file.");
|
||||
} catch ( IOException ioe ) {
|
||||
println("Problem reading settings, IOException: " + ioe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* load properties from system props (command line spec'd usually),
|
||||
* overriding default or file properties
|
||||
*/
|
||||
private void loadSystemProperties() {
|
||||
// override file properties with system properties
|
||||
Properties sysProps = System.getProperties();
|
||||
for (String key : sysProps.stringPropertyNames()) {
|
||||
String value = sysProps.getProperty(key,"");
|
||||
// copy any "awtdebug" properties over
|
||||
if ( key.startsWith(PREFIX) ) {
|
||||
props.setProperty(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets named boolean property
|
||||
* @param key Name of property
|
||||
* @param defval Default value if property does not exist
|
||||
* @return boolean value of the named property
|
||||
*/
|
||||
public synchronized boolean getBoolean(String key, boolean defval) {
|
||||
String value = getString(key, String.valueOf(defval));
|
||||
return value.equalsIgnoreCase("true");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets named integer property
|
||||
* @param key Name of property
|
||||
* @param defval Default value if property does not exist
|
||||
* @return integer value of the named property
|
||||
*/
|
||||
public synchronized int getInt(String key, int defval) {
|
||||
String value = getString(key, String.valueOf(defval));
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets named String property
|
||||
* @param key Name of property
|
||||
* @param defval Default value if property does not exist
|
||||
* @return string value of the named property
|
||||
*/
|
||||
public synchronized String getString(String key, String defval) {
|
||||
String actualKeyName = PREFIX + "." + key;
|
||||
String value = props.getProperty(actualKeyName, defval);
|
||||
//println(actualKeyName+"="+value);
|
||||
return value;
|
||||
}
|
||||
|
||||
private synchronized List<String> getPropertyNames() {
|
||||
List<String> propNames = new LinkedList<>();
|
||||
// remove global prefix from property names
|
||||
for (String propName : props.stringPropertyNames()) {
|
||||
propName = propName.substring(PREFIX.length()+1);
|
||||
propNames.add(propName);
|
||||
}
|
||||
return propNames;
|
||||
}
|
||||
|
||||
private void println(Object object) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer(object.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static final String PROP_CTRACE = "ctrace";
|
||||
private static final int PROP_CTRACE_LEN = PROP_CTRACE.length();
|
||||
|
||||
private native synchronized void setCTracingOn(boolean enabled);
|
||||
private native synchronized void setCTracingOn(boolean enabled, String file);
|
||||
private native synchronized void setCTracingOn(boolean enabled, String file, int line);
|
||||
|
||||
private void loadNativeSettings() {
|
||||
boolean ctracingOn;
|
||||
|
||||
ctracingOn = getBoolean(PROP_CTRACE, false);
|
||||
setCTracingOn(ctracingOn);
|
||||
|
||||
//
|
||||
// Filter out file/line ctrace properties from debug settings
|
||||
//
|
||||
List<String> traces = new LinkedList<>();
|
||||
|
||||
for (String key : getPropertyNames()) {
|
||||
if (key.startsWith(PROP_CTRACE) && key.length() > PROP_CTRACE_LEN) {
|
||||
traces.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
// sort traces list so file-level traces will be before line-level ones
|
||||
Collections.sort(traces);
|
||||
|
||||
//
|
||||
// Setup the trace points
|
||||
//
|
||||
for (String key : traces) {
|
||||
String trace = key.substring(PROP_CTRACE_LEN+1);
|
||||
String filespec;
|
||||
String linespec;
|
||||
int delim= trace.indexOf('@');
|
||||
boolean enabled;
|
||||
|
||||
// parse out the filename and linenumber from the property name
|
||||
filespec = delim != -1 ? trace.substring(0, delim) : trace;
|
||||
linespec = delim != -1 ? trace.substring(delim+1) : "";
|
||||
enabled = getBoolean(key, false);
|
||||
//System.out.println("Key="+key+", File="+filespec+", Line="+linespec+", Enabled="+enabled);
|
||||
|
||||
if ( linespec.length() == 0 ) {
|
||||
// set file specific trace setting
|
||||
setCTracingOn(enabled, filespec);
|
||||
} else {
|
||||
// set line specific trace setting
|
||||
int linenum = Integer.parseInt(linespec, 10);
|
||||
setCTracingOn(enabled, filespec, linenum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/sun/awt/DefaultMouseInfoPeer.java
Normal file
44
jdkSrc/jdk8/sun/awt/DefaultMouseInfoPeer.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 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;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Window;
|
||||
import java.awt.peer.MouseInfoPeer;
|
||||
|
||||
public class DefaultMouseInfoPeer implements MouseInfoPeer {
|
||||
|
||||
/**
|
||||
* Package-private constructor to prevent instantiation.
|
||||
*/
|
||||
DefaultMouseInfoPeer() {
|
||||
}
|
||||
|
||||
public native int fillPointWithCoords(Point point);
|
||||
|
||||
public native boolean isWindowUnderMouse(Window w);
|
||||
|
||||
}
|
||||
46
jdkSrc/jdk8/sun/awt/DesktopBrowse.java
Normal file
46
jdkSrc/jdk8/sun/awt/DesktopBrowse.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 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;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
public abstract class DesktopBrowse {
|
||||
private static volatile DesktopBrowse mInstance;
|
||||
|
||||
public static void setInstance(DesktopBrowse instance) {
|
||||
if (mInstance != null) {
|
||||
throw new IllegalStateException("DesktopBrowse instance has already been set.");
|
||||
}
|
||||
mInstance = instance;
|
||||
}
|
||||
|
||||
public static DesktopBrowse getInstance() {
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
public abstract void browse(URL url);
|
||||
}
|
||||
63
jdkSrc/jdk8/sun/awt/DisplayChangedListener.java
Normal file
63
jdkSrc/jdk8/sun/awt/DisplayChangedListener.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 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;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* The listener interface for receiving display change events.
|
||||
* The class that is interested in processing a display change event
|
||||
* implements this interface (and all the methods it
|
||||
* contains).
|
||||
*
|
||||
* For Motif, this interface is only used for dragging windows between Xinerama
|
||||
* screens.
|
||||
*
|
||||
* For win32, the listener object created from that class is then registered
|
||||
* with the WToolkit object using its <code>addDisplayChangeListener</code>
|
||||
* method. When the display resolution is changed (which occurs,
|
||||
* in Windows, either by the user changing the properties of the
|
||||
* display through the control panel or other utility or by
|
||||
* some other application which has gotten fullscreen-exclusive
|
||||
* control of the display), the listener is notified through its
|
||||
* displayChanged() or paletteChanged() methods.
|
||||
*
|
||||
* @author Chet Haase
|
||||
* @author Brent Christian
|
||||
* @since 1.4
|
||||
*/
|
||||
public interface DisplayChangedListener extends EventListener {
|
||||
/**
|
||||
* Invoked when the display mode has changed.
|
||||
*/
|
||||
public void displayChanged();
|
||||
|
||||
/**
|
||||
* Invoked when the palette has changed.
|
||||
*/
|
||||
public void paletteChanged();
|
||||
|
||||
}
|
||||
586
jdkSrc/jdk8/sun/awt/EmbeddedFrame.java
Normal file
586
jdkSrc/jdk8/sun/awt/EmbeddedFrame.java
Normal file
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2015, 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;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.*;
|
||||
import java.awt.peer.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.Set;
|
||||
import java.awt.AWTKeyStroke;
|
||||
import java.applet.Applet;
|
||||
import sun.applet.AppletPanel;
|
||||
|
||||
/**
|
||||
* A generic container used for embedding Java components, usually applets.
|
||||
* An EmbeddedFrame has two related uses:
|
||||
*
|
||||
* . Within a Java-based application, an EmbeddedFrame serves as a sort of
|
||||
* firewall, preventing the contained components or applets from using
|
||||
* getParent() to find parent components, such as menubars.
|
||||
*
|
||||
* . Within a C-based application, an EmbeddedFrame contains a window handle
|
||||
* which was created by the application, which serves as the top-level
|
||||
* Java window. EmbeddedFrames created for this purpose are passed-in a
|
||||
* handle of an existing window created by the application. The window
|
||||
* handle should be of the appropriate native type for a specific
|
||||
* platform, as stored in the pData field of the ComponentPeer.
|
||||
*
|
||||
* @author Thomas Ball
|
||||
*/
|
||||
public abstract class EmbeddedFrame extends Frame
|
||||
implements KeyEventDispatcher, PropertyChangeListener {
|
||||
|
||||
private boolean isCursorAllowed = true;
|
||||
private boolean supportsXEmbed = false;
|
||||
private KeyboardFocusManager appletKFM;
|
||||
// JDK 1.1 compatibility
|
||||
private static final long serialVersionUID = 2967042741780317130L;
|
||||
|
||||
/*
|
||||
* The constants define focus traversal directions.
|
||||
* Use them in {@code traverseIn}, {@code traverseOut} methods.
|
||||
*/
|
||||
protected static final boolean FORWARD = true;
|
||||
protected static final boolean BACKWARD = false;
|
||||
|
||||
public boolean supportsXEmbed() {
|
||||
return supportsXEmbed && SunToolkit.needsXEmbed();
|
||||
}
|
||||
|
||||
protected EmbeddedFrame(boolean supportsXEmbed) {
|
||||
this((long)0, supportsXEmbed);
|
||||
}
|
||||
|
||||
|
||||
protected EmbeddedFrame() {
|
||||
this((long)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This constructor will be removed in 1.5
|
||||
*/
|
||||
@Deprecated
|
||||
protected EmbeddedFrame(int handle) {
|
||||
this((long)handle);
|
||||
}
|
||||
|
||||
protected EmbeddedFrame(long handle) {
|
||||
this(handle, false);
|
||||
}
|
||||
|
||||
protected EmbeddedFrame(long handle, boolean supportsXEmbed) {
|
||||
this.supportsXEmbed = supportsXEmbed;
|
||||
registerListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Block introspection of a parent window by this child.
|
||||
*/
|
||||
public Container getParent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to track which KeyboardFocusManager is current. We want to avoid memory
|
||||
* leaks, so when KFM stops being current, we remove ourselves as listeners.
|
||||
*/
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
// We don't handle any other properties. Skip it.
|
||||
if (!evt.getPropertyName().equals("managingFocus")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We only do it if it stops being current. Technically, we should
|
||||
// never get an event about KFM starting being current.
|
||||
if (evt.getNewValue() == Boolean.TRUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// should be the same as appletKFM
|
||||
removeTraversingOutListeners((KeyboardFocusManager)evt.getSource());
|
||||
|
||||
appletKFM = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||
if (isVisible()) {
|
||||
addTraversingOutListeners(appletKFM);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register us as KeyEventDispatcher and property "managingFocus" listeners.
|
||||
*/
|
||||
private void addTraversingOutListeners(KeyboardFocusManager kfm) {
|
||||
kfm.addKeyEventDispatcher(this);
|
||||
kfm.addPropertyChangeListener("managingFocus", this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deregister us as KeyEventDispatcher and property "managingFocus" listeners.
|
||||
*/
|
||||
private void removeTraversingOutListeners(KeyboardFocusManager kfm) {
|
||||
kfm.removeKeyEventDispatcher(this);
|
||||
kfm.removePropertyChangeListener("managingFocus", this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Because there may be many AppContexts, and we can't be sure where this
|
||||
* EmbeddedFrame is first created or shown, we can't automatically determine
|
||||
* the correct KeyboardFocusManager to attach to as KeyEventDispatcher.
|
||||
* Those who want to use the functionality of traversing out of the EmbeddedFrame
|
||||
* must call this method on the Applet's AppContext. After that, all the changes
|
||||
* can be handled automatically, including possible replacement of
|
||||
* KeyboardFocusManager.
|
||||
*/
|
||||
public void registerListeners() {
|
||||
if (appletKFM != null) {
|
||||
removeTraversingOutListeners(appletKFM);
|
||||
}
|
||||
appletKFM = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||
if (isVisible()) {
|
||||
addTraversingOutListeners(appletKFM);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to avoid memory leak: we register this EmbeddedFrame as a listener with
|
||||
* KeyboardFocusManager of applet's AppContext. We don't want the KFM to keep
|
||||
* reference to our EmbeddedFrame forever if the Frame is no longer in use, so we
|
||||
* add listeners in show() and remove them in hide().
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void show() {
|
||||
if (appletKFM != null) {
|
||||
addTraversingOutListeners(appletKFM);
|
||||
}
|
||||
super.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to avoid memory leak: we register this EmbeddedFrame as a listener with
|
||||
* KeyboardFocusManager of applet's AppContext. We don't want the KFM to keep
|
||||
* reference to our EmbeddedFrame forever if the Frame is no longer in use, so we
|
||||
* add listeners in show() and remove them in hide().
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void hide() {
|
||||
if (appletKFM != null) {
|
||||
removeTraversingOutListeners(appletKFM);
|
||||
}
|
||||
super.hide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Need this method to detect when the focus may have chance to leave the
|
||||
* focus cycle root which is EmbeddedFrame. Mostly, the code here is copied
|
||||
* from DefaultKeyboardFocusManager.processKeyEvent with some minor
|
||||
* modifications.
|
||||
*/
|
||||
public boolean dispatchKeyEvent(KeyEvent e) {
|
||||
|
||||
Container currentRoot = AWTAccessor.getKeyboardFocusManagerAccessor()
|
||||
.getCurrentFocusCycleRoot();
|
||||
|
||||
// if we are not in EmbeddedFrame's cycle, we should not try to leave.
|
||||
if (this != currentRoot) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// KEY_TYPED events cannot be focus traversal keys
|
||||
if (e.getID() == KeyEvent.KEY_TYPED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getFocusTraversalKeysEnabled() || e.isConsumed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AWTKeyStroke stroke = AWTKeyStroke.getAWTKeyStrokeForEvent(e);
|
||||
Set<AWTKeyStroke> toTest;
|
||||
Component currentFocused = e.getComponent();
|
||||
|
||||
toTest = getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
|
||||
if (toTest.contains(stroke)) {
|
||||
// 6581899: performance improvement for SortingFocusTraversalPolicy
|
||||
Component last = getFocusTraversalPolicy().getLastComponent(this);
|
||||
if (currentFocused == last || last == null) {
|
||||
if (traverseOut(FORWARD)) {
|
||||
e.consume();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toTest = getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
|
||||
if (toTest.contains(stroke)) {
|
||||
// 6581899: performance improvement for SortingFocusTraversalPolicy
|
||||
Component first = getFocusTraversalPolicy().getFirstComponent(this);
|
||||
if (currentFocused == first || first == null) {
|
||||
if (traverseOut(BACKWARD)) {
|
||||
e.consume();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by the embedder when we should receive focus as element
|
||||
* of the traversal chain. The method requests focus on:
|
||||
* 1. the first Component of this EmbeddedFrame if user moves focus forward
|
||||
* in the focus traversal cycle.
|
||||
* 2. the last Component of this EmbeddedFrame if user moves focus backward
|
||||
* in the focus traversal cycle.
|
||||
*
|
||||
* The direction parameter specifies which of the two mentioned cases is
|
||||
* happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class
|
||||
* to avoid confusing boolean values.
|
||||
*
|
||||
* A concrete implementation of this method is defined in the platform-dependent
|
||||
* subclasses.
|
||||
*
|
||||
* @param direction FORWARD or BACKWARD
|
||||
* @return true, if the EmbeddedFrame wants to get focus, false otherwise.
|
||||
*/
|
||||
public boolean traverseIn(boolean direction) {
|
||||
Component comp = null;
|
||||
|
||||
if (direction == FORWARD) {
|
||||
comp = getFocusTraversalPolicy().getFirstComponent(this);
|
||||
} else {
|
||||
comp = getFocusTraversalPolicy().getLastComponent(this);
|
||||
}
|
||||
if (comp != null) {
|
||||
// comp.requestFocus(); - Leads to a hung.
|
||||
|
||||
AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp);
|
||||
synthesizeWindowActivation(true);
|
||||
}
|
||||
return (null != comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from dispatchKeyEvent in the following two cases:
|
||||
* 1. The focus is on the first Component of this EmbeddedFrame and we are
|
||||
* about to transfer the focus backward.
|
||||
* 2. The focus in on the last Component of this EmbeddedFrame and we are
|
||||
* about to transfer the focus forward.
|
||||
* This is needed to give the opportuity for keyboard focus to leave the
|
||||
* EmbeddedFrame. Override this method, initiate focus transfer in it and
|
||||
* return true if you want the focus to leave EmbeddedFrame's cycle.
|
||||
* The direction parameter specifies which of the two mentioned cases is
|
||||
* happening. Use FORWARD and BACKWARD constants defined in EmbeddedFrame
|
||||
* to avoid confusing boolean values.
|
||||
*
|
||||
* @param direction FORWARD or BACKWARD
|
||||
* @return true, if EmbeddedFrame wants the focus to leave it,
|
||||
* false otherwise.
|
||||
*/
|
||||
protected boolean traverseOut(boolean direction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Block modifying any frame attributes, since they aren't applicable
|
||||
* for EmbeddedFrames.
|
||||
*/
|
||||
public void setTitle(String title) {}
|
||||
public void setIconImage(Image image) {}
|
||||
public void setIconImages(java.util.List<? extends Image> icons) {}
|
||||
public void setMenuBar(MenuBar mb) {}
|
||||
public void setResizable(boolean resizable) {}
|
||||
public void remove(MenuComponent m) {}
|
||||
|
||||
public boolean isResizable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void addNotify() {
|
||||
synchronized (getTreeLock()) {
|
||||
if (getPeer() == null) {
|
||||
setPeer(new NullEmbeddedFramePeer());
|
||||
}
|
||||
super.addNotify();
|
||||
}
|
||||
}
|
||||
|
||||
// These three functions consitute RFE 4100710. Do not remove.
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setCursorAllowed(boolean isCursorAllowed) {
|
||||
this.isCursorAllowed = isCursorAllowed;
|
||||
getPeer().updateCursorImmediately();
|
||||
}
|
||||
public boolean isCursorAllowed() {
|
||||
return isCursorAllowed;
|
||||
}
|
||||
public Cursor getCursor() {
|
||||
return (isCursorAllowed)
|
||||
? super.getCursor()
|
||||
: Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void setPeer(final ComponentPeer p){
|
||||
AWTAccessor.getComponentAccessor().setPeer(EmbeddedFrame.this, p);
|
||||
};
|
||||
|
||||
/**
|
||||
* Synthesize native message to activate or deactivate EmbeddedFrame window
|
||||
* depending on the value of parameter <code>b</code>.
|
||||
* Peers should override this method if they are to implement
|
||||
* this functionality.
|
||||
* @param doActivate if <code>true</code>, activates the window;
|
||||
* otherwise, deactivates the window
|
||||
*/
|
||||
public void synthesizeWindowActivation(boolean doActivate) {}
|
||||
|
||||
/**
|
||||
* Moves this embedded frame to a new location. The top-left corner of
|
||||
* the new location is specified by the <code>x</code> and <code>y</code>
|
||||
* parameters relative to the native parent component.
|
||||
* <p>
|
||||
* setLocation() and setBounds() for EmbeddedFrame really don't move it
|
||||
* within the native parent. These methods always put embedded frame to
|
||||
* (0, 0) for backward compatibility. To allow moving embedded frame
|
||||
* setLocationPrivate() and setBoundsPrivate() were introduced, and they
|
||||
* work just the same way as setLocation() and setBounds() for usual,
|
||||
* non-embedded components.
|
||||
* </p>
|
||||
* <p>
|
||||
* Using usual get/setLocation() and get/setBounds() together with new
|
||||
* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.
|
||||
* For example, calling getBoundsPrivate() after setLocation() works fine,
|
||||
* but getBounds() after setBoundsPrivate() may return unpredictable value.
|
||||
* </p>
|
||||
* @param x the new <i>x</i>-coordinate relative to the parent component
|
||||
* @param y the new <i>y</i>-coordinate relative to the parent component
|
||||
* @see java.awt.Component#setLocation
|
||||
* @see #getLocationPrivate
|
||||
* @see #setBoundsPrivate
|
||||
* @see #getBoundsPrivate
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void setLocationPrivate(int x, int y) {
|
||||
Dimension size = getSize();
|
||||
setBoundsPrivate(x, y, size.width, size.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of this embedded frame as a point specifying the
|
||||
* top-left corner relative to parent component.
|
||||
* <p>
|
||||
* setLocation() and setBounds() for EmbeddedFrame really don't move it
|
||||
* within the native parent. These methods always put embedded frame to
|
||||
* (0, 0) for backward compatibility. To allow getting location and size
|
||||
* of embedded frame getLocationPrivate() and getBoundsPrivate() were
|
||||
* introduced, and they work just the same way as getLocation() and getBounds()
|
||||
* for ususal, non-embedded components.
|
||||
* </p>
|
||||
* <p>
|
||||
* Using usual get/setLocation() and get/setBounds() together with new
|
||||
* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.
|
||||
* For example, calling getBoundsPrivate() after setLocation() works fine,
|
||||
* but getBounds() after setBoundsPrivate() may return unpredictable value.
|
||||
* </p>
|
||||
* @return a point indicating this embedded frame's top-left corner
|
||||
* @see java.awt.Component#getLocation
|
||||
* @see #setLocationPrivate
|
||||
* @see #setBoundsPrivate
|
||||
* @see #getBoundsPrivate
|
||||
* @since 1.6
|
||||
*/
|
||||
protected Point getLocationPrivate() {
|
||||
Rectangle bounds = getBoundsPrivate();
|
||||
return new Point(bounds.x, bounds.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves and resizes this embedded frame. The new location of the top-left
|
||||
* corner is specified by <code>x</code> and <code>y</code> parameters
|
||||
* relative to the native parent component. The new size is specified by
|
||||
* <code>width</code> and <code>height</code>.
|
||||
* <p>
|
||||
* setLocation() and setBounds() for EmbeddedFrame really don't move it
|
||||
* within the native parent. These methods always put embedded frame to
|
||||
* (0, 0) for backward compatibility. To allow moving embedded frames
|
||||
* setLocationPrivate() and setBoundsPrivate() were introduced, and they
|
||||
* work just the same way as setLocation() and setBounds() for usual,
|
||||
* non-embedded components.
|
||||
* </p>
|
||||
* <p>
|
||||
* Using usual get/setLocation() and get/setBounds() together with new
|
||||
* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.
|
||||
* For example, calling getBoundsPrivate() after setLocation() works fine,
|
||||
* but getBounds() after setBoundsPrivate() may return unpredictable value.
|
||||
* </p>
|
||||
* @param x the new <i>x</i>-coordinate relative to the parent component
|
||||
* @param y the new <i>y</i>-coordinate relative to the parent component
|
||||
* @param width the new <code>width</code> of this embedded frame
|
||||
* @param height the new <code>height</code> of this embedded frame
|
||||
* @see java.awt.Component#setBounds
|
||||
* @see #setLocationPrivate
|
||||
* @see #getLocationPrivate
|
||||
* @see #getBoundsPrivate
|
||||
* @since 1.5
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void setBoundsPrivate(int x, int y, int width, int height) {
|
||||
final FramePeer peer = (FramePeer)getPeer();
|
||||
if (peer != null) {
|
||||
peer.setBoundsPrivate(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bounds of this embedded frame as a rectangle specifying the
|
||||
* width, height and location relative to the native parent component.
|
||||
* <p>
|
||||
* setLocation() and setBounds() for EmbeddedFrame really don't move it
|
||||
* within the native parent. These methods always put embedded frame to
|
||||
* (0, 0) for backward compatibility. To allow getting location and size
|
||||
* of embedded frames getLocationPrivate() and getBoundsPrivate() were
|
||||
* introduced, and they work just the same way as getLocation() and getBounds()
|
||||
* for ususal, non-embedded components.
|
||||
* </p>
|
||||
* <p>
|
||||
* Using usual get/setLocation() and get/setBounds() together with new
|
||||
* get/setLocationPrivate() and get/setBoundsPrivate() is not recommended.
|
||||
* For example, calling getBoundsPrivate() after setLocation() works fine,
|
||||
* but getBounds() after setBoundsPrivate() may return unpredictable value.
|
||||
* </p>
|
||||
* @return a rectangle indicating this embedded frame's bounds
|
||||
* @see java.awt.Component#getBounds
|
||||
* @see #setLocationPrivate
|
||||
* @see #getLocationPrivate
|
||||
* @see #setBoundsPrivate
|
||||
* @since 1.6
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected Rectangle getBoundsPrivate() {
|
||||
final FramePeer peer = (FramePeer)getPeer();
|
||||
if (peer != null) {
|
||||
return peer.getBoundsPrivate();
|
||||
}
|
||||
else {
|
||||
return getBounds();
|
||||
}
|
||||
}
|
||||
|
||||
public void toFront() {}
|
||||
public void toBack() {}
|
||||
|
||||
public abstract void registerAccelerator(AWTKeyStroke stroke);
|
||||
public abstract void unregisterAccelerator(AWTKeyStroke stroke);
|
||||
|
||||
/**
|
||||
* Checks if the component is in an EmbeddedFrame. If so,
|
||||
* returns the applet found in the hierarchy or null if
|
||||
* not found.
|
||||
* @return the parent applet or {@ null}
|
||||
* @since 1.6
|
||||
*/
|
||||
public static Applet getAppletIfAncestorOf(Component comp) {
|
||||
Container parent = comp.getParent();
|
||||
Applet applet = null;
|
||||
while (parent != null && !(parent instanceof EmbeddedFrame)) {
|
||||
if (parent instanceof Applet) {
|
||||
applet = (Applet)parent;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
}
|
||||
return parent == null ? null : applet;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overriden in subclasses. It is
|
||||
* called when window this frame is within should be blocked
|
||||
* by some modal dialog.
|
||||
*/
|
||||
public void notifyModalBlocked(Dialog blocker, boolean blocked) {
|
||||
}
|
||||
|
||||
private static class NullEmbeddedFramePeer
|
||||
extends NullComponentPeer implements FramePeer {
|
||||
public void setTitle(String title) {}
|
||||
public void setIconImage(Image im) {}
|
||||
public void updateIconImages() {}
|
||||
public void setMenuBar(MenuBar mb) {}
|
||||
public void setResizable(boolean resizeable) {}
|
||||
public void setState(int state) {}
|
||||
public int getState() { return Frame.NORMAL; }
|
||||
public void setMaximizedBounds(Rectangle b) {}
|
||||
public void toFront() {}
|
||||
public void toBack() {}
|
||||
public void updateFocusableWindowState() {}
|
||||
public void updateAlwaysOnTop() {}
|
||||
public void updateAlwaysOnTopState() {}
|
||||
public Component getGlobalHeavyweightFocusOwner() { return null; }
|
||||
public void setBoundsPrivate(int x, int y, int width, int height) {
|
||||
setBounds(x, y, width, height, SET_BOUNDS);
|
||||
}
|
||||
public Rectangle getBoundsPrivate() {
|
||||
return getBounds();
|
||||
}
|
||||
public void setModalBlocked(Dialog blocker, boolean blocked) {}
|
||||
|
||||
/**
|
||||
* @see java.awt.peer.ContainerPeer#restack
|
||||
*/
|
||||
public void restack() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.peer.ContainerPeer#isRestackSupported
|
||||
*/
|
||||
public boolean isRestackSupported() {
|
||||
return false;
|
||||
}
|
||||
public boolean requestWindowFocus() {
|
||||
return false;
|
||||
}
|
||||
public void updateMinimumSize() {
|
||||
}
|
||||
|
||||
public void setOpacity(float opacity) {
|
||||
}
|
||||
|
||||
public void setOpaque(boolean isOpaque) {
|
||||
}
|
||||
|
||||
public void updateWindow() {
|
||||
}
|
||||
|
||||
public void repositionSecurityWarning() {
|
||||
}
|
||||
|
||||
public void emulateActivation(boolean activate) {
|
||||
}
|
||||
}
|
||||
} // class EmbeddedFrame
|
||||
175
jdkSrc/jdk8/sun/awt/EventListenerAggregate.java
Normal file
175
jdkSrc/jdk8/sun/awt/EventListenerAggregate.java
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, 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;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.EventListener;
|
||||
|
||||
|
||||
/**
|
||||
* A class that assists in managing {@link java.util.EventListener}s of
|
||||
* the specified type. Its instance holds an array of listeners of the same
|
||||
* type and allows to perform the typical operations on the listeners.
|
||||
* This class is thread-safe.
|
||||
*
|
||||
* @author Alexander Gerasimov
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class EventListenerAggregate {
|
||||
|
||||
private EventListener[] listenerList;
|
||||
|
||||
/**
|
||||
* Constructs an <code>EventListenerAggregate</code> object.
|
||||
*
|
||||
* @param listenerClass the type of the listeners to be managed by this object
|
||||
*
|
||||
* @throws NullPointerException if <code>listenerClass</code> is
|
||||
* <code>null</code>
|
||||
* @throws ClassCastException if <code>listenerClass</code> is not
|
||||
* assignable to <code>java.util.EventListener</code>
|
||||
*/
|
||||
public EventListenerAggregate(Class<? extends EventListener> listenerClass) {
|
||||
if (listenerClass == null) {
|
||||
throw new NullPointerException("listener class is null");
|
||||
}
|
||||
|
||||
listenerList = (EventListener[])Array.newInstance(listenerClass, 0);
|
||||
}
|
||||
|
||||
private Class<?> getListenerClass() {
|
||||
return listenerList.getClass().getComponentType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the listener to this aggregate.
|
||||
*
|
||||
* @param listener the listener to be added
|
||||
*
|
||||
* @throws ClassCastException if <code>listener</code> is not
|
||||
* an instatce of <code>listenerClass</code> specified
|
||||
* in the constructor
|
||||
*/
|
||||
public synchronized void add(EventListener listener) {
|
||||
Class<?> listenerClass = getListenerClass();
|
||||
|
||||
if (!listenerClass.isInstance(listener)) { // null is not an instance of any class
|
||||
throw new ClassCastException("listener " + listener + " is not " +
|
||||
"an instance of listener class " + listenerClass);
|
||||
}
|
||||
|
||||
EventListener[] tmp = (EventListener[])Array.newInstance(listenerClass, listenerList.length + 1);
|
||||
System.arraycopy(listenerList, 0, tmp, 0, listenerList.length);
|
||||
tmp[listenerList.length] = listener;
|
||||
listenerList = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener that is equal to the given one from this aggregate.
|
||||
* <code>equals()</code> method is used to compare listeners.
|
||||
*
|
||||
* @param listener the listener to be removed
|
||||
*
|
||||
* @return <code>true</code> if this aggregate contained the specified
|
||||
* <code>listener</code>; <code>false</code> otherwise
|
||||
*
|
||||
* @throws ClassCastException if <code>listener</code> is not
|
||||
* an instatce of <code>listenerClass</code> specified
|
||||
* in the constructor
|
||||
*/
|
||||
public synchronized boolean remove(EventListener listener) {
|
||||
Class<?> listenerClass = getListenerClass();
|
||||
|
||||
if (!listenerClass.isInstance(listener)) { // null is not an instance of any class
|
||||
throw new ClassCastException("listener " + listener + " is not " +
|
||||
"an instance of listener class " + listenerClass);
|
||||
}
|
||||
|
||||
for (int i = 0; i < listenerList.length; i++) {
|
||||
if (listenerList[i].equals(listener)) {
|
||||
EventListener[] tmp = (EventListener[])Array.newInstance(listenerClass,
|
||||
listenerList.length - 1);
|
||||
System.arraycopy(listenerList, 0, tmp, 0, i);
|
||||
System.arraycopy(listenerList, i + 1, tmp, i, listenerList.length - i - 1);
|
||||
listenerList = tmp;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the listeners contained in this aggregate.
|
||||
* The array is the data structure in which listeners are stored internally.
|
||||
* The runtime type of the returned array is "array of <code>listenerClass</code>"
|
||||
* (<code>listenerClass</code> has been specified as a parameter to
|
||||
* the constructor of this class).
|
||||
*
|
||||
* @return all the listeners contained in this aggregate (an empty
|
||||
* array if there are no listeners)
|
||||
*/
|
||||
public synchronized EventListener[] getListenersInternal() {
|
||||
return listenerList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the listeners contained in this aggregate.
|
||||
* The array is a copy of the data structure in which listeners are stored
|
||||
* internally.
|
||||
* The runtime type of the returned array is "array of <code>listenerClass</code>"
|
||||
* (<code>listenerClass</code> has been specified as a parameter to
|
||||
* the constructor of this class).
|
||||
*
|
||||
* @return a copy of all the listeners contained in this aggregate (an empty
|
||||
* array if there are no listeners)
|
||||
*/
|
||||
public synchronized EventListener[] getListenersCopy() {
|
||||
return (listenerList.length == 0) ? listenerList : listenerList.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of lisetners in this aggregate.
|
||||
*
|
||||
* @return the number of lisetners in this aggregate
|
||||
*/
|
||||
public synchronized int size() {
|
||||
return listenerList.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this aggregate contains no listeners,
|
||||
* <code>false</code> otherwise.
|
||||
*
|
||||
* @return <code>true</code> if this aggregate contains no listeners,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public synchronized boolean isEmpty() {
|
||||
return listenerList.length == 0;
|
||||
}
|
||||
}
|
||||
71
jdkSrc/jdk8/sun/awt/EventQueueDelegate.java
Normal file
71
jdkSrc/jdk8/sun/awt/EventQueueDelegate.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 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;
|
||||
|
||||
import java.awt.AWTEvent;
|
||||
import java.awt.EventQueue;
|
||||
|
||||
|
||||
public class EventQueueDelegate {
|
||||
private static final Object EVENT_QUEUE_DELEGATE_KEY =
|
||||
new StringBuilder("EventQueueDelegate.Delegate");
|
||||
|
||||
public static void setDelegate(Delegate delegate) {
|
||||
AppContext.getAppContext().put(EVENT_QUEUE_DELEGATE_KEY, delegate);
|
||||
}
|
||||
public static Delegate getDelegate() {
|
||||
return
|
||||
(Delegate) AppContext.getAppContext().get(EVENT_QUEUE_DELEGATE_KEY);
|
||||
}
|
||||
public interface Delegate {
|
||||
/**
|
||||
* This method allows for changing {@code EventQueue} events order.
|
||||
*
|
||||
* @param eventQueue current {@code EventQueue}
|
||||
* @return next {@code event} for the {@code EventDispatchThread}
|
||||
*/
|
||||
|
||||
public AWTEvent getNextEvent(EventQueue eventQueue) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Notifies delegate before EventQueue.dispatch method.
|
||||
*
|
||||
* Note: this method may mutate the event
|
||||
*
|
||||
* @param event to be dispatched by {@code dispatch} method
|
||||
* @return handle to be passed to {@code afterDispatch} method
|
||||
*/
|
||||
public Object beforeDispatch(AWTEvent event) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Notifies delegate after EventQueue.dispatch method.
|
||||
*
|
||||
* @param event {@code event} dispatched by the {@code dispatch} method
|
||||
* @param handle object which came from {@code beforeDispatch} method
|
||||
*/
|
||||
public void afterDispatch(AWTEvent event, Object handle) throws InterruptedException;
|
||||
}
|
||||
}
|
||||
37
jdkSrc/jdk8/sun/awt/EventQueueItem.java
Normal file
37
jdkSrc/jdk8/sun/awt/EventQueueItem.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 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;
|
||||
|
||||
import java.awt.AWTEvent;
|
||||
|
||||
public class EventQueueItem {
|
||||
public AWTEvent event;
|
||||
public EventQueueItem next;
|
||||
|
||||
public EventQueueItem(AWTEvent evt) {
|
||||
event = evt;
|
||||
}
|
||||
}
|
||||
669
jdkSrc/jdk8/sun/awt/ExtendedKeyCodes.java
Normal file
669
jdkSrc/jdk8/sun/awt/ExtendedKeyCodes.java
Normal file
@@ -0,0 +1,669 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2018, 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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
public class ExtendedKeyCodes {
|
||||
/**
|
||||
* ATTN: These are the readonly hashes with load factor == 1;
|
||||
* adding a value, please set the inital capacity to exact number of items
|
||||
* or higher.
|
||||
*/
|
||||
// Keycodes declared in KeyEvent.java with corresponding Unicode values.
|
||||
private final static HashMap<Integer, Integer> regularKeyCodesMap =
|
||||
new HashMap<Integer,Integer>(98, 1.0f);
|
||||
|
||||
// Keycodes derived from Unicode values. Here should be collected codes
|
||||
// for characters appearing on the primary layer of at least one
|
||||
// known keyboard layout. For instance, sterling sign is on the primary layer
|
||||
// of the Mac Italian layout.
|
||||
private final static HashSet<Integer> extendedKeyCodesSet =
|
||||
new HashSet<Integer>(501, 1.0f);
|
||||
final public static int getExtendedKeyCodeForChar( int c ) {
|
||||
int uc = Character.toUpperCase( c );
|
||||
int lc = Character.toLowerCase( c );
|
||||
if (regularKeyCodesMap.containsKey( c )) {
|
||||
if(regularKeyCodesMap.containsKey(uc)) {
|
||||
return regularKeyCodesMap.get( uc );
|
||||
}
|
||||
return regularKeyCodesMap.get( c );
|
||||
}
|
||||
uc += 0x01000000;
|
||||
lc += 0x01000000;
|
||||
if (extendedKeyCodesSet.contains( uc )) {
|
||||
return uc;
|
||||
}else if (extendedKeyCodesSet.contains( lc )) {
|
||||
return lc;
|
||||
}
|
||||
return KeyEvent.VK_UNDEFINED;
|
||||
}
|
||||
static {
|
||||
regularKeyCodesMap.put(0x08, KeyEvent.VK_BACK_SPACE);
|
||||
regularKeyCodesMap.put(0x09, KeyEvent.VK_TAB);
|
||||
regularKeyCodesMap.put(0x0a, KeyEvent.VK_ENTER);
|
||||
regularKeyCodesMap.put(0x1B, KeyEvent.VK_ESCAPE);
|
||||
regularKeyCodesMap.put(0x20AC, KeyEvent.VK_EURO_SIGN);
|
||||
regularKeyCodesMap.put(0x20, KeyEvent.VK_SPACE);
|
||||
regularKeyCodesMap.put(0x21, KeyEvent.VK_EXCLAMATION_MARK);
|
||||
regularKeyCodesMap.put(0x22, KeyEvent.VK_QUOTEDBL);
|
||||
regularKeyCodesMap.put(0x23, KeyEvent.VK_NUMBER_SIGN);
|
||||
regularKeyCodesMap.put(0x24, KeyEvent.VK_DOLLAR);
|
||||
regularKeyCodesMap.put(0x26, KeyEvent.VK_AMPERSAND);
|
||||
regularKeyCodesMap.put(0x27, KeyEvent.VK_QUOTE);
|
||||
regularKeyCodesMap.put(0x28, KeyEvent.VK_LEFT_PARENTHESIS);
|
||||
regularKeyCodesMap.put(0x29, KeyEvent.VK_RIGHT_PARENTHESIS);
|
||||
regularKeyCodesMap.put(0x2A, KeyEvent.VK_ASTERISK);
|
||||
regularKeyCodesMap.put(0x2B, KeyEvent.VK_PLUS);
|
||||
regularKeyCodesMap.put(0x2C, KeyEvent.VK_COMMA);
|
||||
regularKeyCodesMap.put(0x2D, KeyEvent.VK_MINUS);
|
||||
regularKeyCodesMap.put(0x2E, KeyEvent.VK_PERIOD);
|
||||
regularKeyCodesMap.put(0x2F, KeyEvent.VK_SLASH);
|
||||
regularKeyCodesMap.put(0x30, KeyEvent.VK_0);
|
||||
regularKeyCodesMap.put(0x31, KeyEvent.VK_1);
|
||||
regularKeyCodesMap.put(0x32, KeyEvent.VK_2);
|
||||
regularKeyCodesMap.put(0x33, KeyEvent.VK_3);
|
||||
regularKeyCodesMap.put(0x34, KeyEvent.VK_4);
|
||||
regularKeyCodesMap.put(0x35, KeyEvent.VK_5);
|
||||
regularKeyCodesMap.put(0x36, KeyEvent.VK_6);
|
||||
regularKeyCodesMap.put(0x37, KeyEvent.VK_7);
|
||||
regularKeyCodesMap.put(0x38, KeyEvent.VK_8);
|
||||
regularKeyCodesMap.put(0x39, KeyEvent.VK_9);
|
||||
regularKeyCodesMap.put(0x3A, KeyEvent.VK_COLON);
|
||||
regularKeyCodesMap.put(0x3B, KeyEvent.VK_SEMICOLON);
|
||||
regularKeyCodesMap.put(0x3C, KeyEvent.VK_LESS);
|
||||
regularKeyCodesMap.put(0x3D, KeyEvent.VK_EQUALS);
|
||||
regularKeyCodesMap.put(0x3E, KeyEvent.VK_GREATER);
|
||||
regularKeyCodesMap.put(0x40, KeyEvent.VK_AT);
|
||||
regularKeyCodesMap.put(0x41, KeyEvent.VK_A);
|
||||
regularKeyCodesMap.put(0x42, KeyEvent.VK_B);
|
||||
regularKeyCodesMap.put(0x43, KeyEvent.VK_C);
|
||||
regularKeyCodesMap.put(0x44, KeyEvent.VK_D);
|
||||
regularKeyCodesMap.put(0x45, KeyEvent.VK_E);
|
||||
regularKeyCodesMap.put(0x46, KeyEvent.VK_F);
|
||||
regularKeyCodesMap.put(0x47, KeyEvent.VK_G);
|
||||
regularKeyCodesMap.put(0x48, KeyEvent.VK_H);
|
||||
regularKeyCodesMap.put(0x49, KeyEvent.VK_I);
|
||||
regularKeyCodesMap.put(0x4A, KeyEvent.VK_J);
|
||||
regularKeyCodesMap.put(0x4B, KeyEvent.VK_K);
|
||||
regularKeyCodesMap.put(0x4C, KeyEvent.VK_L);
|
||||
regularKeyCodesMap.put(0x4D, KeyEvent.VK_M);
|
||||
regularKeyCodesMap.put(0x4E, KeyEvent.VK_N);
|
||||
regularKeyCodesMap.put(0x4F, KeyEvent.VK_O);
|
||||
regularKeyCodesMap.put(0x50, KeyEvent.VK_P);
|
||||
regularKeyCodesMap.put(0x51, KeyEvent.VK_Q);
|
||||
regularKeyCodesMap.put(0x52, KeyEvent.VK_R);
|
||||
regularKeyCodesMap.put(0x53, KeyEvent.VK_S);
|
||||
regularKeyCodesMap.put(0x54, KeyEvent.VK_T);
|
||||
regularKeyCodesMap.put(0x55, KeyEvent.VK_U);
|
||||
regularKeyCodesMap.put(0x56, KeyEvent.VK_V);
|
||||
regularKeyCodesMap.put(0x57, KeyEvent.VK_W);
|
||||
regularKeyCodesMap.put(0x58, KeyEvent.VK_X);
|
||||
regularKeyCodesMap.put(0x59, KeyEvent.VK_Y);
|
||||
regularKeyCodesMap.put(0x5A, KeyEvent.VK_Z);
|
||||
regularKeyCodesMap.put(0x5B, KeyEvent.VK_OPEN_BRACKET);
|
||||
regularKeyCodesMap.put(0x5C, KeyEvent.VK_BACK_SLASH);
|
||||
regularKeyCodesMap.put(0x5D, KeyEvent.VK_CLOSE_BRACKET);
|
||||
regularKeyCodesMap.put(0x5E, KeyEvent.VK_CIRCUMFLEX);
|
||||
regularKeyCodesMap.put(0x5F, KeyEvent.VK_UNDERSCORE);
|
||||
regularKeyCodesMap.put(0x60, KeyEvent.VK_BACK_QUOTE);
|
||||
regularKeyCodesMap.put(0x61, KeyEvent.VK_A);
|
||||
regularKeyCodesMap.put(0x62, KeyEvent.VK_B);
|
||||
regularKeyCodesMap.put(0x63, KeyEvent.VK_C);
|
||||
regularKeyCodesMap.put(0x64, KeyEvent.VK_D);
|
||||
regularKeyCodesMap.put(0x65, KeyEvent.VK_E);
|
||||
regularKeyCodesMap.put(0x66, KeyEvent.VK_F);
|
||||
regularKeyCodesMap.put(0x67, KeyEvent.VK_G);
|
||||
regularKeyCodesMap.put(0x68, KeyEvent.VK_H);
|
||||
regularKeyCodesMap.put(0x69, KeyEvent.VK_I);
|
||||
regularKeyCodesMap.put(0x6A, KeyEvent.VK_J);
|
||||
regularKeyCodesMap.put(0x6B, KeyEvent.VK_K);
|
||||
regularKeyCodesMap.put(0x6C, KeyEvent.VK_L);
|
||||
regularKeyCodesMap.put(0x6D, KeyEvent.VK_M);
|
||||
regularKeyCodesMap.put(0x6E, KeyEvent.VK_N);
|
||||
regularKeyCodesMap.put(0x6F, KeyEvent.VK_O);
|
||||
regularKeyCodesMap.put(0x70, KeyEvent.VK_P);
|
||||
regularKeyCodesMap.put(0x71, KeyEvent.VK_Q);
|
||||
regularKeyCodesMap.put(0x72, KeyEvent.VK_R);
|
||||
regularKeyCodesMap.put(0x73, KeyEvent.VK_S);
|
||||
regularKeyCodesMap.put(0x74, KeyEvent.VK_T);
|
||||
regularKeyCodesMap.put(0x75, KeyEvent.VK_U);
|
||||
regularKeyCodesMap.put(0x76, KeyEvent.VK_V);
|
||||
regularKeyCodesMap.put(0x77, KeyEvent.VK_W);
|
||||
regularKeyCodesMap.put(0x78, KeyEvent.VK_X);
|
||||
regularKeyCodesMap.put(0x79, KeyEvent.VK_Y);
|
||||
regularKeyCodesMap.put(0x7A, KeyEvent.VK_Z);
|
||||
regularKeyCodesMap.put(0x7B, KeyEvent.VK_BRACELEFT);
|
||||
regularKeyCodesMap.put(0x7D, KeyEvent.VK_BRACERIGHT);
|
||||
regularKeyCodesMap.put(0x7F, KeyEvent.VK_DELETE);
|
||||
regularKeyCodesMap.put(0xA1, KeyEvent.VK_INVERTED_EXCLAMATION_MARK);
|
||||
|
||||
extendedKeyCodesSet.add(0x01000000+0x0060);
|
||||
extendedKeyCodesSet.add(0x01000000+0x007C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x007E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00A2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00A3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00A5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00A7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00A8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00AB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00B0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00B1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00B2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00B3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00B4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00B5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00B6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00B7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00B9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00BA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00BB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00BC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00BD);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00BE);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00BF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00C4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00C5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00C6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00C7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00D1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00D6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00D7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00D8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00DF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00E0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00E1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00E2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00E4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00E5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00E6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00E7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00E8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00E9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00EA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00EB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00EC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00ED);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00EE);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00F0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00F1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00F2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00F3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00F4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00F5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00F6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00F7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00F8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00F9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00FA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00FB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00FC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00FD);
|
||||
extendedKeyCodesSet.add(0x01000000+0x00FE);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0105);
|
||||
extendedKeyCodesSet.add(0x01000000+0x02DB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0142);
|
||||
extendedKeyCodesSet.add(0x01000000+0x013E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x015B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0161);
|
||||
extendedKeyCodesSet.add(0x01000000+0x015F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0165);
|
||||
extendedKeyCodesSet.add(0x01000000+0x017E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x017C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0103);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0107);
|
||||
extendedKeyCodesSet.add(0x01000000+0x010D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0119);
|
||||
extendedKeyCodesSet.add(0x01000000+0x011B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0111);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0148);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0151);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0171);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0159);
|
||||
extendedKeyCodesSet.add(0x01000000+0x016F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0163);
|
||||
extendedKeyCodesSet.add(0x01000000+0x02D9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0130);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0127);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0125);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0131);
|
||||
extendedKeyCodesSet.add(0x01000000+0x011F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0135);
|
||||
extendedKeyCodesSet.add(0x01000000+0x010B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0109);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0121);
|
||||
extendedKeyCodesSet.add(0x01000000+0x011D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x016D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x015D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0138);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0157);
|
||||
extendedKeyCodesSet.add(0x01000000+0x013C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0113);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0123);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0167);
|
||||
extendedKeyCodesSet.add(0x01000000+0x014B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0101);
|
||||
extendedKeyCodesSet.add(0x01000000+0x012F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0117);
|
||||
extendedKeyCodesSet.add(0x01000000+0x012B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0146);
|
||||
extendedKeyCodesSet.add(0x01000000+0x014D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0137);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0173);
|
||||
extendedKeyCodesSet.add(0x01000000+0x016B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0153);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30FC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30A2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30A4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30A6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30A8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30AA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30AB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30AD);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30AF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30B1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30B3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30B5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30B7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30B9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30BB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30BD);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30BF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30C1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30C4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30C6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30C8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30CA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30CB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30CC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30CD);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30CE);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30CF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30D2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30D5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30D8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30DB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30DE);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30DF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30E0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30E1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30E2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30E4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30E6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30E8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30E9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30EA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30EB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30EC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30ED);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30EF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x30F3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x309B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x309C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06F0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06F1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06F2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06F3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06F4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06F5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06F6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06F7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06F8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06F9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0670);
|
||||
extendedKeyCodesSet.add(0x01000000+0x067E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0686);
|
||||
extendedKeyCodesSet.add(0x01000000+0x060C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06D4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0660);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0661);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0662);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0663);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0664);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0665);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0666);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0667);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0668);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0669);
|
||||
extendedKeyCodesSet.add(0x01000000+0x061B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0621);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0624);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0626);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0627);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0628);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0629);
|
||||
extendedKeyCodesSet.add(0x01000000+0x062A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x062B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x062C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x062D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x062E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x062F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0630);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0631);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0632);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0633);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0634);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0635);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0636);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0637);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0638);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0639);
|
||||
extendedKeyCodesSet.add(0x01000000+0x063A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0641);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0642);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0643);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0644);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0645);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0646);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0647);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0648);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0649);
|
||||
extendedKeyCodesSet.add(0x01000000+0x064A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x064E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x064F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0650);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0652);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0698);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06A4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06A9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06AF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06BE);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06CC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06CC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x06D2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0493);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0497);
|
||||
extendedKeyCodesSet.add(0x01000000+0x049B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x049D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x04A3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x04AF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x04B1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x04B3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x04B9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x04BB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x04D9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x04E9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0452);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0453);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0451);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0454);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0455);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0456);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0457);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0458);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0459);
|
||||
extendedKeyCodesSet.add(0x01000000+0x045A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x045B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x045C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0491);
|
||||
extendedKeyCodesSet.add(0x01000000+0x045E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x045F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x2116);
|
||||
extendedKeyCodesSet.add(0x01000000+0x044E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0430);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0431);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0446);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0434);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0435);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0444);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0433);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0445);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0438);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0439);
|
||||
extendedKeyCodesSet.add(0x01000000+0x043A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x043B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x043C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x043D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x043E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x043F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x044F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0440);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0441);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0442);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0443);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0436);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0432);
|
||||
extendedKeyCodesSet.add(0x01000000+0x044C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x044B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0437);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0448);
|
||||
extendedKeyCodesSet.add(0x01000000+0x044D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0449);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0447);
|
||||
extendedKeyCodesSet.add(0x01000000+0x044A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x2015);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03B1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03B2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03B3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03B4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03B5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03B6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03B7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03B8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03B9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03BA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03BB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03BC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03BD);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03BE);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03BF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03C0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03C1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03C3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03C2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03C4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03C5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03C6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03C7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03C8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x03C9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x2190);
|
||||
extendedKeyCodesSet.add(0x01000000+0x2192);
|
||||
extendedKeyCodesSet.add(0x01000000+0x2193);
|
||||
extendedKeyCodesSet.add(0x01000000+0x2013);
|
||||
extendedKeyCodesSet.add(0x01000000+0x201C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x201D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x201E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05D0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05D1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05D2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05D3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05D4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05D5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05D6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05D7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05D8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05D9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05DA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05DB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05DC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05DD);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05DE);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05DF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05E0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05E1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05E2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05E3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05E4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05E5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05E6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05E7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05E8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05E9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x05EA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E01);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E02);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E03);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E04);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E05);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E07);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E08);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E0A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E0C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E14);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E15);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E16);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E17);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E19);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E1A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E1B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E1C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E1D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E1E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E1F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E20);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E21);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E22);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E23);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E25);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E27);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E2A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E2B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E2D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E30);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E31);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E32);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E33);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E34);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E35);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E36);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E37);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E38);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E39);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E3F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E40);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E41);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E43);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E44);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E45);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E46);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E47);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E48);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E49);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E50);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E51);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E52);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E53);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E54);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E55);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E56);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E57);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E58);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0E59);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0587);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0589);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0589);
|
||||
extendedKeyCodesSet.add(0x01000000+0x055D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x055D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x055B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x055B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x055E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x055E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0561);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0562);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0563);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0564);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0565);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0566);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0567);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0568);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0569);
|
||||
extendedKeyCodesSet.add(0x01000000+0x056A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x056B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x056C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x056D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x056E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x056F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0570);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0571);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0572);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0573);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0574);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0575);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0576);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0577);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0578);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0579);
|
||||
extendedKeyCodesSet.add(0x01000000+0x057A);
|
||||
extendedKeyCodesSet.add(0x01000000+0x057B);
|
||||
extendedKeyCodesSet.add(0x01000000+0x057C);
|
||||
extendedKeyCodesSet.add(0x01000000+0x057D);
|
||||
extendedKeyCodesSet.add(0x01000000+0x057E);
|
||||
extendedKeyCodesSet.add(0x01000000+0x057F);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0580);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0581);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0582);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0583);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0584);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0585);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0586);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10D0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10D1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10D2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10D3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10D4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10D5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10D6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10D7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10D8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10D9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10DA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10DB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10DC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10DD);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10DE);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10DF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10E0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10E1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10E2);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10E3);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10E4);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10E5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10E6);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10E7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10E8);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10E9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10EA);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10EB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10EC);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10ED);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10EE);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10EF);
|
||||
extendedKeyCodesSet.add(0x01000000+0x10F0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x01E7);
|
||||
extendedKeyCodesSet.add(0x01000000+0x0259);
|
||||
extendedKeyCodesSet.add(0x01000000+0x1EB9);
|
||||
extendedKeyCodesSet.add(0x01000000+0x1ECB);
|
||||
extendedKeyCodesSet.add(0x01000000+0x1ECD);
|
||||
extendedKeyCodesSet.add(0x01000000+0x1EE5);
|
||||
extendedKeyCodesSet.add(0x01000000+0x01A1);
|
||||
extendedKeyCodesSet.add(0x01000000+0x01B0);
|
||||
extendedKeyCodesSet.add(0x01000000+0x20AB);
|
||||
}
|
||||
}
|
||||
2287
jdkSrc/jdk8/sun/awt/FontConfiguration.java
Normal file
2287
jdkSrc/jdk8/sun/awt/FontConfiguration.java
Normal file
File diff suppressed because it is too large
Load Diff
121
jdkSrc/jdk8/sun/awt/FontDescriptor.java
Normal file
121
jdkSrc/jdk8/sun/awt/FontDescriptor.java
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2011, 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;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import sun.nio.cs.HistoricallyNamedCharset;
|
||||
|
||||
public class FontDescriptor implements Cloneable {
|
||||
|
||||
static {
|
||||
NativeLibLoader.loadLibraries();
|
||||
initIDs();
|
||||
}
|
||||
|
||||
String nativeName;
|
||||
public CharsetEncoder encoder;
|
||||
String charsetName;
|
||||
private int[] exclusionRanges;
|
||||
|
||||
public FontDescriptor(String nativeName, CharsetEncoder encoder,
|
||||
int[] exclusionRanges){
|
||||
|
||||
this.nativeName = nativeName;
|
||||
this.encoder = encoder;
|
||||
this.exclusionRanges = exclusionRanges;
|
||||
this.useUnicode = false;
|
||||
Charset cs = encoder.charset();
|
||||
if (cs instanceof HistoricallyNamedCharset)
|
||||
this.charsetName = ((HistoricallyNamedCharset)cs).historicalName();
|
||||
else
|
||||
this.charsetName = cs.name();
|
||||
|
||||
}
|
||||
|
||||
public String getNativeName() {
|
||||
return nativeName;
|
||||
}
|
||||
|
||||
public CharsetEncoder getFontCharsetEncoder() {
|
||||
return encoder;
|
||||
}
|
||||
|
||||
public String getFontCharsetName() {
|
||||
return charsetName;
|
||||
}
|
||||
|
||||
public int[] getExclusionRanges() {
|
||||
return exclusionRanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the character is exclusion character.
|
||||
*/
|
||||
public boolean isExcluded(char ch){
|
||||
for (int i = 0; i < exclusionRanges.length; ){
|
||||
|
||||
int lo = (exclusionRanges[i++]);
|
||||
int up = (exclusionRanges[i++]);
|
||||
|
||||
if (ch >= lo && ch <= up){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + " [" + nativeName + "|" + encoder + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize JNI field and method IDs
|
||||
*/
|
||||
private static native void initIDs();
|
||||
|
||||
|
||||
public CharsetEncoder unicodeEncoder;
|
||||
boolean useUnicode; // set to true from native code on Unicode-based systems
|
||||
|
||||
public boolean useUnicode() {
|
||||
if (useUnicode && unicodeEncoder == null) {
|
||||
try {
|
||||
this.unicodeEncoder = isLE?
|
||||
StandardCharsets.UTF_16LE.newEncoder():
|
||||
StandardCharsets.UTF_16BE.newEncoder();
|
||||
} catch (IllegalArgumentException x) {}
|
||||
}
|
||||
return useUnicode;
|
||||
}
|
||||
static boolean isLE;
|
||||
static {
|
||||
String enc = (String) java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("sun.io.unicode.encoding",
|
||||
"UnicodeBig"));
|
||||
isLE = !"UnicodeBig".equals(enc);
|
||||
}
|
||||
}
|
||||
59
jdkSrc/jdk8/sun/awt/FwDispatcher.java
Normal file
59
jdkSrc/jdk8/sun/awt/FwDispatcher.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* An interface for the EventQueue delegate.
|
||||
* This class is added to support JavaFX/AWT interop single threaded mode
|
||||
* The delegate should be set in EventQueue by {@link EventQueue#setFwDispatcher(FwDispatcher)}
|
||||
* If the delegate is not null, than it handles supported methods instead of the
|
||||
* event queue. If it is null than the behaviour of an event queue does not change.
|
||||
*
|
||||
* @see EventQueue
|
||||
*
|
||||
* @author Petr Pchelko
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface FwDispatcher {
|
||||
/**
|
||||
* Delegates the {@link EventQueue#isDispatchThread()} method
|
||||
*/
|
||||
boolean isDispatchThread();
|
||||
|
||||
/**
|
||||
* Forwards a runnable to the delegate, which executes it on an appropriate thread.
|
||||
* @param r - a runnable calling {@link EventQueue#dispatchEventImpl(java.awt.AWTEvent, Object)}
|
||||
*/
|
||||
void scheduleDispatch(Runnable r);
|
||||
|
||||
/**
|
||||
* Delegates the {@link java.awt.EventQueue#createSecondaryLoop()} method
|
||||
*/
|
||||
SecondaryLoop createSecondaryLoop();
|
||||
}
|
||||
216
jdkSrc/jdk8/sun/awt/GlobalCursorManager.java
Normal file
216
jdkSrc/jdk8/sun/awt/GlobalCursorManager.java
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, 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;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.InvocationEvent;
|
||||
|
||||
/**
|
||||
* A stateless class which responds to native mouse moves, Component resizes,
|
||||
* Component moves, showing and hiding of Components, minimizing and
|
||||
* maximizing of top level Windows, addition and removal of Components,
|
||||
* and calls to setCursor().
|
||||
*/
|
||||
public abstract class GlobalCursorManager {
|
||||
|
||||
class NativeUpdater implements Runnable {
|
||||
boolean pending = false;
|
||||
|
||||
public void run() {
|
||||
boolean shouldUpdate = false;
|
||||
synchronized (this) {
|
||||
if (pending) {
|
||||
pending = false;
|
||||
shouldUpdate = true;
|
||||
}
|
||||
}
|
||||
if (shouldUpdate) {
|
||||
_updateCursor(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void postIfNotPending(Component heavy, InvocationEvent in) {
|
||||
boolean shouldPost = false;
|
||||
synchronized (this) {
|
||||
if (!pending) {
|
||||
pending = shouldPost = true;
|
||||
}
|
||||
}
|
||||
if (shouldPost) {
|
||||
SunToolkit.postEvent(SunToolkit.targetToAppContext(heavy), in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a singleton NativeUpdater for better performance. We cannot use
|
||||
* a singleton InvocationEvent because we want each event to have a fresh
|
||||
* timestamp.
|
||||
*/
|
||||
private final NativeUpdater nativeUpdater = new NativeUpdater();
|
||||
|
||||
/**
|
||||
* The last time the cursor was updated, in milliseconds.
|
||||
*/
|
||||
private long lastUpdateMillis;
|
||||
|
||||
/**
|
||||
* Locking object for synchronizing access to lastUpdateMillis. The VM
|
||||
* does not guarantee atomicity of longs.
|
||||
*/
|
||||
private final Object lastUpdateLock = new Object();
|
||||
|
||||
/**
|
||||
* Should be called for any activity at the Java level which may affect
|
||||
* the global cursor, except for Java MOUSE_MOVED events.
|
||||
*/
|
||||
public void updateCursorImmediately() {
|
||||
synchronized (nativeUpdater) {
|
||||
nativeUpdater.pending = false;
|
||||
}
|
||||
_updateCursor(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called in response to Java MOUSE_MOVED events. The update
|
||||
* will be discarded if the InputEvent is outdated.
|
||||
*
|
||||
* @param e the InputEvent which triggered the cursor update.
|
||||
*/
|
||||
public void updateCursorImmediately(InputEvent e) {
|
||||
boolean shouldUpdate;
|
||||
synchronized (lastUpdateLock) {
|
||||
shouldUpdate = (e.getWhen() >= lastUpdateMillis);
|
||||
}
|
||||
if (shouldUpdate) {
|
||||
_updateCursor(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called in response to a native mouse enter or native mouse
|
||||
* button released message. Should not be called during a mouse drag.
|
||||
*/
|
||||
public void updateCursorLater(Component heavy) {
|
||||
nativeUpdater.postIfNotPending(heavy, new InvocationEvent
|
||||
(Toolkit.getDefaultToolkit(), nativeUpdater));
|
||||
}
|
||||
|
||||
protected GlobalCursorManager() { }
|
||||
|
||||
/**
|
||||
* Set the global cursor to the specified cursor. The component over
|
||||
* which the Cursor current resides is provided as a convenience. Not
|
||||
* all platforms may require the Component.
|
||||
*/
|
||||
protected abstract void setCursor(Component comp, Cursor cursor,
|
||||
boolean useCache);
|
||||
/**
|
||||
* Returns the global cursor position, in screen coordinates.
|
||||
*/
|
||||
protected abstract void getCursorPos(Point p);
|
||||
|
||||
protected abstract Point getLocationOnScreen(Component com);
|
||||
|
||||
/**
|
||||
* Returns the most specific, visible, heavyweight Component
|
||||
* under the cursor. This method should return null iff the cursor is
|
||||
* not over any Java Window.
|
||||
*
|
||||
* @param useCache If true, the implementation is free to use caching
|
||||
* mechanisms because the Z-order, visibility, and enabled state of the
|
||||
* Components has not changed. If false, the implementation should not
|
||||
* make these assumptions.
|
||||
*/
|
||||
protected abstract Component findHeavyweightUnderCursor(boolean useCache);
|
||||
|
||||
/**
|
||||
* Updates the global cursor. We apply a three-step scheme to cursor
|
||||
* updates:<p>
|
||||
*
|
||||
* (1) InputEvent updates which are outdated are discarded by
|
||||
* <code>updateCursorImmediately(InputEvent)</code>.<p>
|
||||
*
|
||||
* (2) If 'useCache' is true, the native code is free to use a cached
|
||||
* value to determine the most specific, visible, enabled heavyweight
|
||||
* because this update is occurring in response to a mouse move. If
|
||||
* 'useCache' is false, the native code must perform a new search given
|
||||
* the current mouse coordinates.
|
||||
*
|
||||
* (3) Once we have determined the most specific, visible, enabled
|
||||
* heavyweight, we use findComponentAt to find the most specific, visible,
|
||||
* enabled Component.
|
||||
*/
|
||||
private void _updateCursor(boolean useCache) {
|
||||
|
||||
synchronized (lastUpdateLock) {
|
||||
lastUpdateMillis = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
Point queryPos = null, p = null;
|
||||
Component comp;
|
||||
|
||||
try {
|
||||
comp = findHeavyweightUnderCursor(useCache);
|
||||
if (comp == null) {
|
||||
updateCursorOutOfJava();
|
||||
return;
|
||||
}
|
||||
|
||||
if (comp instanceof Window) {
|
||||
p = AWTAccessor.getComponentAccessor().getLocation(comp);
|
||||
} else if (comp instanceof Container) {
|
||||
p = getLocationOnScreen(comp);
|
||||
}
|
||||
if (p != null) {
|
||||
queryPos = new Point();
|
||||
getCursorPos(queryPos);
|
||||
Component c = AWTAccessor.getContainerAccessor().
|
||||
findComponentAt((Container) comp,
|
||||
queryPos.x - p.x, queryPos.y - p.y, false);
|
||||
|
||||
// If findComponentAt returns null, then something bad has
|
||||
// happened. For example, the heavyweight Component may
|
||||
// have been hidden or disabled by another thread. In that
|
||||
// case, we'll just use the originial heavyweight.
|
||||
if (c != null) {
|
||||
comp = c;
|
||||
}
|
||||
}
|
||||
|
||||
setCursor(comp, AWTAccessor.getComponentAccessor().getCursor(comp), useCache);
|
||||
|
||||
} catch (IllegalComponentStateException e) {
|
||||
// Shouldn't happen, but if it does, abort.
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateCursorOutOfJava() {
|
||||
// Cursor is not over a Java Window. Do nothing...usually
|
||||
// But we need to update it in case of grab on X.
|
||||
}
|
||||
}
|
||||
33
jdkSrc/jdk8/sun/awt/Graphics2Delegate.java
Normal file
33
jdkSrc/jdk8/sun/awt/Graphics2Delegate.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
|
||||
public interface Graphics2Delegate {
|
||||
void setBackground(Color color);
|
||||
}
|
||||
44
jdkSrc/jdk8/sun/awt/HKSCS.java
Normal file
44
jdkSrc/jdk8/sun/awt/HKSCS.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, 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;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
|
||||
/* 2d/XMap and WFontConfiguration implementation need access HKSCS,
|
||||
make a subclass here to avoid expose HKSCS to the public in
|
||||
ExtendedCharsets class, because if we want to have a public HKSCS,
|
||||
it probably should be HKSCS_2001 not HKSCS.
|
||||
*/
|
||||
public class HKSCS extends sun.nio.cs.ext.MS950_HKSCS_XP {
|
||||
public HKSCS () {
|
||||
super();
|
||||
}
|
||||
public boolean contains(Charset cs) {
|
||||
return (cs instanceof HKSCS);
|
||||
}
|
||||
}
|
||||
392
jdkSrc/jdk8/sun/awt/HToolkit.java
Normal file
392
jdkSrc/jdk8/sun/awt/HToolkit.java
Normal file
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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;
|
||||
|
||||
import sun.awt.datatransfer.DataTransferer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.dnd.*;
|
||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||
import java.awt.im.InputMethodHighlight;
|
||||
import java.awt.im.spi.InputMethodDescriptor;
|
||||
import java.awt.image.*;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.peer.*;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/*
|
||||
* HToolkit is a platform independent Toolkit used
|
||||
* with the HeadlessToolkit. It is primarily used
|
||||
* in embedded JRE's that do not have sun/awt/X11 classes.
|
||||
*/
|
||||
public class HToolkit extends SunToolkit
|
||||
implements ComponentFactory {
|
||||
|
||||
private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
|
||||
public void setCurrentFocusedWindow(Window win) {}
|
||||
public Window getCurrentFocusedWindow() { return null; }
|
||||
public void setCurrentFocusOwner(Component comp) {}
|
||||
public Component getCurrentFocusOwner() { return null; }
|
||||
public void clearGlobalFocusOwner(Window activeWindow) {}
|
||||
};
|
||||
|
||||
public HToolkit() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Component peer objects - unsupported.
|
||||
*/
|
||||
|
||||
public WindowPeer createWindow(Window target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public FramePeer createLightweightFrame(LightweightFrame target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public FramePeer createFrame(Frame target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public DialogPeer createDialog(Dialog target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ButtonPeer createButton(Button target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public TextFieldPeer createTextField(TextField target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ChoicePeer createChoice(Choice target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public LabelPeer createLabel(Label target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ListPeer createList(List target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public CheckboxPeer createCheckbox(Checkbox target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ScrollbarPeer createScrollbar(Scrollbar target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ScrollPanePeer createScrollPane(ScrollPane target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public TextAreaPeer createTextArea(TextArea target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public FileDialogPeer createFileDialog(FileDialog target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public MenuBarPeer createMenuBar(MenuBar target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public MenuPeer createMenu(Menu target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public PopupMenuPeer createPopupMenu(PopupMenu target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public MenuItemPeer createMenuItem(MenuItem target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public DragSourceContextPeer createDragSourceContextPeer(
|
||||
DragGestureEvent dge)
|
||||
throws InvalidDnDOperationException {
|
||||
throw new InvalidDnDOperationException("Headless environment");
|
||||
}
|
||||
|
||||
public RobotPeer createRobot(Robot target, GraphicsDevice screen)
|
||||
throws AWTException, HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
|
||||
// See 6833019.
|
||||
return kfmPeer;
|
||||
}
|
||||
|
||||
public TrayIconPeer createTrayIcon(TrayIcon target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public SystemTrayPeer createSystemTray(SystemTray target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public boolean isTraySupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataTransferer getDataTransferer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public GlobalCursorManager getGlobalCursorManager()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
/*
|
||||
* Headless toolkit - unsupported.
|
||||
*/
|
||||
protected void loadSystemColors(int[] systemColors)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ColorModel getColorModel()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public int getScreenResolution()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Map mapInputMethodHighlight(InputMethodHighlight highlight)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public int getMenuShortcutKeyMask()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public boolean getLockingKeyState(int keyCode)
|
||||
throws UnsupportedOperationException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public void setLockingKeyState(int keyCode, boolean on)
|
||||
throws UnsupportedOperationException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
|
||||
throws IndexOutOfBoundsException, HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Dimension getBestCursorSize(int preferredWidth, int preferredHeight)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public int getMaximumCursorColors()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public <T extends DragGestureRecognizer> T
|
||||
createDragGestureRecognizer(Class<T> abstractRecognizerClass,
|
||||
DragSource ds, Component c,
|
||||
int srcActions, DragGestureListener dgl)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getScreenHeight()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public int getScreenWidth()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Dimension getScreenSize()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Insets getScreenInsets(GraphicsConfiguration gc)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public void setDynamicLayout(boolean dynamic)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
protected boolean isDynamicLayoutSet()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public boolean isDynamicLayoutActive()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Clipboard getSystemClipboard()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
/*
|
||||
* Printing
|
||||
*/
|
||||
public PrintJob getPrintJob(Frame frame, String jobtitle,
|
||||
JobAttributes jobAttributes,
|
||||
PageAttributes pageAttributes) {
|
||||
if (frame != null) {
|
||||
// Should never happen
|
||||
throw new HeadlessException();
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"PrintJob not supported in a headless environment");
|
||||
}
|
||||
|
||||
public PrintJob getPrintJob(Frame frame, String doctitle, Properties props)
|
||||
{
|
||||
if (frame != null) {
|
||||
// Should never happen
|
||||
throw new HeadlessException();
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"PrintJob not supported in a headless environment");
|
||||
}
|
||||
|
||||
/*
|
||||
* Headless toolkit - supported.
|
||||
*/
|
||||
|
||||
public void sync() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
protected boolean syncNativeQueue(final long timeout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void beep() {
|
||||
// Send alert character
|
||||
System.out.write(0x07);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fonts
|
||||
*/
|
||||
public FontPeer getFontPeer(String name, int style) {
|
||||
return (FontPeer)null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modality
|
||||
*/
|
||||
public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isDesktopSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public DesktopPeer createDesktopPeer(Desktop target)
|
||||
throws HeadlessException{
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public boolean isWindowOpacityControlSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isWindowShapingSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isWindowTranslucencySupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void grab(Window w) { }
|
||||
|
||||
public void ungrab(Window w) { }
|
||||
|
||||
protected boolean syncNativeQueue() { return false; }
|
||||
|
||||
public InputMethodDescriptor getInputMethodAdapterDescriptor()
|
||||
throws AWTException
|
||||
{
|
||||
return (InputMethodDescriptor)null;
|
||||
}
|
||||
}
|
||||
486
jdkSrc/jdk8/sun/awt/HeadlessToolkit.java
Normal file
486
jdkSrc/jdk8/sun/awt/HeadlessToolkit.java
Normal file
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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;
|
||||
|
||||
import sun.awt.datatransfer.DataTransferer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.dnd.*;
|
||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||
import java.awt.event.*;
|
||||
import java.awt.im.InputMethodHighlight;
|
||||
import java.awt.image.*;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.peer.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class HeadlessToolkit extends Toolkit
|
||||
implements ComponentFactory, KeyboardFocusManagerPeerProvider {
|
||||
|
||||
private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
|
||||
public void setCurrentFocusedWindow(Window win) {}
|
||||
public Window getCurrentFocusedWindow() { return null; }
|
||||
public void setCurrentFocusOwner(Component comp) {}
|
||||
public Component getCurrentFocusOwner() { return null; }
|
||||
public void clearGlobalFocusOwner(Window activeWindow) {}
|
||||
};
|
||||
|
||||
private Toolkit tk;
|
||||
private ComponentFactory componentFactory;
|
||||
|
||||
public HeadlessToolkit(Toolkit tk) {
|
||||
this.tk = tk;
|
||||
if (tk instanceof ComponentFactory) {
|
||||
componentFactory = (ComponentFactory)tk;
|
||||
}
|
||||
}
|
||||
|
||||
public Toolkit getUnderlyingToolkit() {
|
||||
return tk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Component peer objects.
|
||||
*/
|
||||
|
||||
/* Lightweight implementation of Canvas and Panel */
|
||||
|
||||
public CanvasPeer createCanvas(Canvas target) {
|
||||
return (CanvasPeer)createComponent(target);
|
||||
}
|
||||
|
||||
public PanelPeer createPanel(Panel target) {
|
||||
return (PanelPeer)createComponent(target);
|
||||
}
|
||||
|
||||
/*
|
||||
* Component peer objects - unsupported.
|
||||
*/
|
||||
|
||||
public WindowPeer createWindow(Window target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public FramePeer createFrame(Frame target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public DialogPeer createDialog(Dialog target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ButtonPeer createButton(Button target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public TextFieldPeer createTextField(TextField target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ChoicePeer createChoice(Choice target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public LabelPeer createLabel(Label target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ListPeer createList(List target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public CheckboxPeer createCheckbox(Checkbox target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ScrollbarPeer createScrollbar(Scrollbar target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ScrollPanePeer createScrollPane(ScrollPane target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public TextAreaPeer createTextArea(TextArea target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public FileDialogPeer createFileDialog(FileDialog target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public MenuBarPeer createMenuBar(MenuBar target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public MenuPeer createMenu(Menu target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public PopupMenuPeer createPopupMenu(PopupMenu target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public MenuItemPeer createMenuItem(MenuItem target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public DragSourceContextPeer createDragSourceContextPeer(
|
||||
DragGestureEvent dge)
|
||||
throws InvalidDnDOperationException {
|
||||
throw new InvalidDnDOperationException("Headless environment");
|
||||
}
|
||||
|
||||
public RobotPeer createRobot(Robot target, GraphicsDevice screen)
|
||||
throws AWTException, HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
|
||||
// See 6833019.
|
||||
return kfmPeer;
|
||||
}
|
||||
|
||||
public TrayIconPeer createTrayIcon(TrayIcon target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public SystemTrayPeer createSystemTray(SystemTray target)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public boolean isTraySupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public GlobalCursorManager getGlobalCursorManager()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
/*
|
||||
* Headless toolkit - unsupported.
|
||||
*/
|
||||
protected void loadSystemColors(int[] systemColors)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public ColorModel getColorModel()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public int getScreenResolution()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Map mapInputMethodHighlight(InputMethodHighlight highlight)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public int getMenuShortcutKeyMask()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public boolean getLockingKeyState(int keyCode)
|
||||
throws UnsupportedOperationException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public void setLockingKeyState(int keyCode, boolean on)
|
||||
throws UnsupportedOperationException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
|
||||
throws IndexOutOfBoundsException, HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Dimension getBestCursorSize(int preferredWidth, int preferredHeight)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public int getMaximumCursorColors()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public <T extends DragGestureRecognizer> T
|
||||
createDragGestureRecognizer(Class<T> abstractRecognizerClass,
|
||||
DragSource ds, Component c,
|
||||
int srcActions, DragGestureListener dgl)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getScreenHeight()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public int getScreenWidth()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Dimension getScreenSize()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Insets getScreenInsets(GraphicsConfiguration gc)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public void setDynamicLayout(boolean dynamic)
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
protected boolean isDynamicLayoutSet()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public boolean isDynamicLayoutActive()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public Clipboard getSystemClipboard()
|
||||
throws HeadlessException {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
/*
|
||||
* Printing
|
||||
*/
|
||||
public PrintJob getPrintJob(Frame frame, String jobtitle,
|
||||
JobAttributes jobAttributes,
|
||||
PageAttributes pageAttributes) {
|
||||
if (frame != null) {
|
||||
// Should never happen
|
||||
throw new HeadlessException();
|
||||
}
|
||||
throw new NullPointerException("frame must not be null");
|
||||
}
|
||||
|
||||
public PrintJob getPrintJob(Frame frame, String doctitle, Properties props)
|
||||
{
|
||||
if (frame != null) {
|
||||
// Should never happen
|
||||
throw new HeadlessException();
|
||||
}
|
||||
throw new NullPointerException("frame must not be null");
|
||||
}
|
||||
|
||||
/*
|
||||
* Headless toolkit - supported.
|
||||
*/
|
||||
|
||||
public void sync() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public void beep() {
|
||||
// Send alert character
|
||||
System.out.write(0x07);
|
||||
}
|
||||
|
||||
/*
|
||||
* Event Queue
|
||||
*/
|
||||
public EventQueue getSystemEventQueueImpl() {
|
||||
return SunToolkit.getSystemEventQueueImplPP();
|
||||
}
|
||||
|
||||
/*
|
||||
* Images.
|
||||
*/
|
||||
public int checkImage(Image img, int w, int h, ImageObserver o) {
|
||||
return tk.checkImage(img, w, h, o);
|
||||
}
|
||||
|
||||
public boolean prepareImage(
|
||||
Image img, int w, int h, ImageObserver o) {
|
||||
return tk.prepareImage(img, w, h, o);
|
||||
}
|
||||
|
||||
public Image getImage(String filename) {
|
||||
return tk.getImage(filename);
|
||||
}
|
||||
|
||||
public Image getImage(URL url) {
|
||||
return tk.getImage(url);
|
||||
}
|
||||
|
||||
public Image createImage(String filename) {
|
||||
return tk.createImage(filename);
|
||||
}
|
||||
|
||||
public Image createImage(URL url) {
|
||||
return tk.createImage(url);
|
||||
}
|
||||
|
||||
public Image createImage(byte[] data, int offset, int length) {
|
||||
return tk.createImage(data, offset, length);
|
||||
}
|
||||
|
||||
public Image createImage(ImageProducer producer) {
|
||||
return tk.createImage(producer);
|
||||
}
|
||||
|
||||
public Image createImage(byte[] imagedata) {
|
||||
return tk.createImage(imagedata);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fonts
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public FontPeer getFontPeer(String name, int style) {
|
||||
if (componentFactory != null) {
|
||||
return componentFactory.getFontPeer(name, style);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataTransferer getDataTransferer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public FontMetrics getFontMetrics(Font font) {
|
||||
return tk.getFontMetrics(font);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public String[] getFontList() {
|
||||
return tk.getFontList();
|
||||
}
|
||||
|
||||
/*
|
||||
* Desktop properties
|
||||
*/
|
||||
|
||||
public void addPropertyChangeListener(String name,
|
||||
PropertyChangeListener pcl) {
|
||||
tk.addPropertyChangeListener(name, pcl);
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(String name,
|
||||
PropertyChangeListener pcl) {
|
||||
tk.removePropertyChangeListener(name, pcl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Modality
|
||||
*/
|
||||
public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Always on top
|
||||
*/
|
||||
public boolean isAlwaysOnTopSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* AWT Event listeners
|
||||
*/
|
||||
|
||||
public void addAWTEventListener(AWTEventListener listener,
|
||||
long eventMask) {
|
||||
tk.addAWTEventListener(listener, eventMask);
|
||||
}
|
||||
|
||||
public void removeAWTEventListener(AWTEventListener listener) {
|
||||
tk.removeAWTEventListener(listener);
|
||||
}
|
||||
|
||||
public AWTEventListener[] getAWTEventListeners() {
|
||||
return tk.getAWTEventListeners();
|
||||
}
|
||||
|
||||
public AWTEventListener[] getAWTEventListeners(long eventMask) {
|
||||
return tk.getAWTEventListeners(eventMask);
|
||||
}
|
||||
|
||||
public boolean isDesktopSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public DesktopPeer createDesktopPeer(Desktop target)
|
||||
throws HeadlessException{
|
||||
throw new HeadlessException();
|
||||
}
|
||||
|
||||
public boolean areExtraMouseButtonsEnabled() throws HeadlessException{
|
||||
throw new HeadlessException();
|
||||
}
|
||||
}
|
||||
237
jdkSrc/jdk8/sun/awt/IconInfo.java
Normal file
237
jdkSrc/jdk8/sun/awt/IconInfo.java
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2013, 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;
|
||||
import java.awt.*;
|
||||
import java.awt.color.*;
|
||||
import java.awt.image.*;
|
||||
import sun.awt.image.ToolkitImage;
|
||||
import sun.awt.image.ImageRepresentation;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class IconInfo {
|
||||
/**
|
||||
* Representation of image as an int array.
|
||||
* It's used on platforms where icon data
|
||||
* is expected to be in 32-bit format.
|
||||
*/
|
||||
private int[] intIconData;
|
||||
/**
|
||||
* Representation of image as an long array.
|
||||
* It's used on platforms where icon data
|
||||
* is expected to be in 64-bit format.
|
||||
*/
|
||||
private long[] longIconData;
|
||||
/**
|
||||
* Icon image.
|
||||
*/
|
||||
private Image image;
|
||||
/**
|
||||
* Width of icon image. Being set in constructor.
|
||||
*/
|
||||
private final int width;
|
||||
/**
|
||||
* Height of icon image. Being set in constructor.
|
||||
*/
|
||||
private final int height;
|
||||
/**
|
||||
* Width of scaled icon image. Can be set in setScaledDimension.
|
||||
*/
|
||||
private int scaledWidth;
|
||||
/**
|
||||
* Height of scaled icon image. Can be set in setScaledDimension.
|
||||
*/
|
||||
private int scaledHeight;
|
||||
/**
|
||||
* Length of raw data. Being set in constructor / setScaledDimension.
|
||||
*/
|
||||
private int rawLength;
|
||||
|
||||
public IconInfo(int[] intIconData) {
|
||||
this.intIconData =
|
||||
(null == intIconData) ? null : Arrays.copyOf(intIconData, intIconData.length);
|
||||
this.width = intIconData[0];
|
||||
this.height = intIconData[1];
|
||||
this.scaledWidth = width;
|
||||
this.scaledHeight = height;
|
||||
this.rawLength = width * height + 2;
|
||||
}
|
||||
|
||||
public IconInfo(long[] longIconData) {
|
||||
this.longIconData =
|
||||
(null == longIconData) ? null : Arrays.copyOf(longIconData, longIconData.length);
|
||||
this.width = (int)longIconData[0];
|
||||
this.height = (int)longIconData[1];
|
||||
this.scaledWidth = width;
|
||||
this.scaledHeight = height;
|
||||
this.rawLength = width * height + 2;
|
||||
}
|
||||
|
||||
public IconInfo(Image image) {
|
||||
this.image = image;
|
||||
if (image instanceof ToolkitImage) {
|
||||
ImageRepresentation ir = ((ToolkitImage)image).getImageRep();
|
||||
ir.reconstruct(ImageObserver.ALLBITS);
|
||||
this.width = ir.getWidth();
|
||||
this.height = ir.getHeight();
|
||||
} else {
|
||||
this.width = image.getWidth(null);
|
||||
this.height = image.getHeight(null);
|
||||
}
|
||||
this.scaledWidth = width;
|
||||
this.scaledHeight = height;
|
||||
this.rawLength = width * height + 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* It sets size of scaled icon.
|
||||
*/
|
||||
public void setScaledSize(int width, int height) {
|
||||
this.scaledWidth = width;
|
||||
this.scaledHeight = height;
|
||||
this.rawLength = width * height + 2;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return (width > 0 && height > 0);
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "IconInfo[w=" + width + ",h=" + height + ",sw=" + scaledWidth + ",sh=" + scaledHeight + "]";
|
||||
}
|
||||
|
||||
public int getRawLength() {
|
||||
return rawLength;
|
||||
}
|
||||
|
||||
public int[] getIntData() {
|
||||
if (this.intIconData == null) {
|
||||
if (this.longIconData != null) {
|
||||
this.intIconData = longArrayToIntArray(longIconData);
|
||||
} else if (this.image != null) {
|
||||
this.intIconData = imageToIntArray(this.image, scaledWidth, scaledHeight);
|
||||
}
|
||||
}
|
||||
return this.intIconData;
|
||||
}
|
||||
|
||||
public long[] getLongData() {
|
||||
if (this.longIconData == null) {
|
||||
if (this.intIconData != null) {
|
||||
this.longIconData = intArrayToLongArray(this.intIconData);
|
||||
} else if (this.image != null) {
|
||||
int[] intIconData = imageToIntArray(this.image, scaledWidth, scaledHeight);
|
||||
this.longIconData = intArrayToLongArray(intIconData);
|
||||
}
|
||||
}
|
||||
return this.longIconData;
|
||||
}
|
||||
|
||||
public Image getImage() {
|
||||
if (this.image == null) {
|
||||
if (this.intIconData != null) {
|
||||
this.image = intArrayToImage(this.intIconData);
|
||||
} else if (this.longIconData != null) {
|
||||
int[] intIconData = longArrayToIntArray(this.longIconData);
|
||||
this.image = intArrayToImage(intIconData);
|
||||
}
|
||||
}
|
||||
return this.image;
|
||||
}
|
||||
|
||||
private static int[] longArrayToIntArray(long[] longData) {
|
||||
int[] intData = new int[longData.length];
|
||||
for (int i = 0; i < longData.length; i++) {
|
||||
// Such a conversion is valid since the
|
||||
// original data (see
|
||||
// make/sun/xawt/ToBin.java) were ints
|
||||
intData[i] = (int)longData[i];
|
||||
}
|
||||
return intData;
|
||||
}
|
||||
|
||||
private static long[] intArrayToLongArray(int[] intData) {
|
||||
long[] longData = new long[intData.length];
|
||||
for (int i = 0; i < intData.length; i++) {
|
||||
longData[i] = (int)intData[i];
|
||||
}
|
||||
return longData;
|
||||
}
|
||||
|
||||
static Image intArrayToImage(int[] raw) {
|
||||
ColorModel cm =
|
||||
new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32,
|
||||
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000,
|
||||
false, DataBuffer.TYPE_INT);
|
||||
DataBuffer buffer = new DataBufferInt(raw, raw.length-2, 2);
|
||||
WritableRaster raster =
|
||||
Raster.createPackedRaster(buffer, raw[0], raw[1],
|
||||
raw[0],
|
||||
new int[] {0x00ff0000, 0x0000ff00,
|
||||
0x000000ff, 0xff000000},
|
||||
null);
|
||||
BufferedImage im = new BufferedImage(cm, raster, false, null);
|
||||
return im;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns array of integers which holds data for the image.
|
||||
* It scales the image if necessary.
|
||||
*/
|
||||
static int[] imageToIntArray(Image image, int width, int height) {
|
||||
if (width <= 0 || height <= 0) {
|
||||
return null;
|
||||
}
|
||||
ColorModel cm =
|
||||
new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32,
|
||||
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000,
|
||||
false, DataBuffer.TYPE_INT);
|
||||
DataBufferInt buffer = new DataBufferInt(width * height);
|
||||
WritableRaster raster =
|
||||
Raster.createPackedRaster(buffer, width, height,
|
||||
width,
|
||||
new int[] {0x00ff0000, 0x0000ff00,
|
||||
0x000000ff, 0xff000000},
|
||||
null);
|
||||
BufferedImage im = new BufferedImage(cm, raster, false, null);
|
||||
Graphics g = im.getGraphics();
|
||||
g.drawImage(image, 0, 0, width, height, null);
|
||||
g.dispose();
|
||||
int[] data = buffer.getData();
|
||||
int[] raw = new int[width * height + 2];
|
||||
raw[0] = width;
|
||||
raw[1] = height;
|
||||
System.arraycopy(data, 0, raw, 2, width * height);
|
||||
return raw;
|
||||
}
|
||||
|
||||
}
|
||||
57
jdkSrc/jdk8/sun/awt/InputMethodSupport.java
Normal file
57
jdkSrc/jdk8/sun/awt/InputMethodSupport.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.Window;
|
||||
import java.awt.im.spi.InputMethodDescriptor;
|
||||
import java.util.Locale;
|
||||
import sun.awt.im.InputContext;
|
||||
|
||||
/**
|
||||
* Input method support for toolkits
|
||||
*/
|
||||
public interface InputMethodSupport {
|
||||
/**
|
||||
* Returns a new input method adapter descriptor for native input methods.
|
||||
*/
|
||||
InputMethodDescriptor getInputMethodAdapterDescriptor()
|
||||
throws AWTException;
|
||||
/**
|
||||
* Returns a new input method window for the platform
|
||||
*/
|
||||
Window createInputMethodWindow(String title, InputContext context);
|
||||
|
||||
/**
|
||||
* Returns whether input methods are enabled on the platform
|
||||
*/
|
||||
boolean enableInputMethodsForTextComponent();
|
||||
|
||||
/**
|
||||
* Returns the default keyboard locale of the underlying operating system.
|
||||
*/
|
||||
Locale getDefaultKeyboardLocale();
|
||||
}
|
||||
181
jdkSrc/jdk8/sun/awt/KeyboardFocusManagerPeerImpl.java
Normal file
181
jdkSrc/jdk8/sun/awt/KeyboardFocusManagerPeerImpl.java
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, 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;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Window;
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Scrollbar;
|
||||
import java.awt.Panel;
|
||||
|
||||
import java.awt.event.FocusEvent;
|
||||
|
||||
import java.awt.peer.KeyboardFocusManagerPeer;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
public abstract class KeyboardFocusManagerPeerImpl implements KeyboardFocusManagerPeer {
|
||||
|
||||
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.focus.KeyboardFocusManagerPeerImpl");
|
||||
|
||||
private static class KfmAccessor {
|
||||
private static AWTAccessor.KeyboardFocusManagerAccessor instance =
|
||||
AWTAccessor.getKeyboardFocusManagerAccessor();
|
||||
}
|
||||
|
||||
// The constants are copied from java.awt.KeyboardFocusManager
|
||||
public static final int SNFH_FAILURE = 0;
|
||||
public static final int SNFH_SUCCESS_HANDLED = 1;
|
||||
public static final int SNFH_SUCCESS_PROCEED = 2;
|
||||
|
||||
@Override
|
||||
public void clearGlobalFocusOwner(Window activeWindow) {
|
||||
if (activeWindow != null) {
|
||||
Component focusOwner = activeWindow.getFocusOwner();
|
||||
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
focusLog.fine("Clearing global focus owner " + focusOwner);
|
||||
}
|
||||
if (focusOwner != null) {
|
||||
FocusEvent fl = new CausedFocusEvent(focusOwner, FocusEvent.FOCUS_LOST, false, null,
|
||||
CausedFocusEvent.Cause.CLEAR_GLOBAL_FOCUS_OWNER);
|
||||
SunToolkit.postPriorityEvent(fl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING: Don't call it on the Toolkit thread.
|
||||
*
|
||||
* Checks if the component:
|
||||
* 1) accepts focus on click (in general)
|
||||
* 2) may be a focus owner (in particular)
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static boolean shouldFocusOnClick(Component component) {
|
||||
boolean acceptFocusOnClick = false;
|
||||
|
||||
// A component is generally allowed to accept focus on click
|
||||
// if its peer is focusable. There're some exceptions though.
|
||||
|
||||
|
||||
// CANVAS & SCROLLBAR accept focus on click
|
||||
if (component instanceof Canvas ||
|
||||
component instanceof Scrollbar)
|
||||
{
|
||||
acceptFocusOnClick = true;
|
||||
|
||||
// PANEL, empty only, accepts focus on click
|
||||
} else if (component instanceof Panel) {
|
||||
acceptFocusOnClick = (((Panel)component).getComponentCount() == 0);
|
||||
|
||||
|
||||
// Other components
|
||||
} else {
|
||||
ComponentPeer peer = (component != null ? component.getPeer() : null);
|
||||
acceptFocusOnClick = (peer != null ? peer.isFocusable() : false);
|
||||
}
|
||||
return acceptFocusOnClick &&
|
||||
AWTAccessor.getComponentAccessor().canBeFocusOwner(component);
|
||||
}
|
||||
|
||||
/*
|
||||
* Posts proper lost/gain focus events to the event queue.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static boolean deliverFocus(Component lightweightChild,
|
||||
Component target,
|
||||
boolean temporary,
|
||||
boolean focusedWindowChangeAllowed,
|
||||
long time,
|
||||
CausedFocusEvent.Cause cause,
|
||||
Component currentFocusOwner) // provided by the descendant peers
|
||||
{
|
||||
if (lightweightChild == null) {
|
||||
lightweightChild = target;
|
||||
}
|
||||
|
||||
Component currentOwner = currentFocusOwner;
|
||||
if (currentOwner != null && currentOwner.getPeer() == null) {
|
||||
currentOwner = null;
|
||||
}
|
||||
if (currentOwner != null) {
|
||||
FocusEvent fl = new CausedFocusEvent(currentOwner, FocusEvent.FOCUS_LOST,
|
||||
false, lightweightChild, cause);
|
||||
|
||||
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
focusLog.finer("Posting focus event: " + fl);
|
||||
}
|
||||
SunToolkit.postEvent(SunToolkit.targetToAppContext(currentOwner), fl);
|
||||
}
|
||||
|
||||
FocusEvent fg = new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED,
|
||||
false, currentOwner, cause);
|
||||
|
||||
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
focusLog.finer("Posting focus event: " + fg);
|
||||
}
|
||||
SunToolkit.postEvent(SunToolkit.targetToAppContext(lightweightChild), fg);
|
||||
return true;
|
||||
}
|
||||
|
||||
// WARNING: Don't call it on the Toolkit thread.
|
||||
public static boolean requestFocusFor(Component target, CausedFocusEvent.Cause cause) {
|
||||
return AWTAccessor.getComponentAccessor().requestFocus(target, cause);
|
||||
}
|
||||
|
||||
// WARNING: Don't call it on the Toolkit thread.
|
||||
public static int shouldNativelyFocusHeavyweight(Component heavyweight,
|
||||
Component descendant,
|
||||
boolean temporary,
|
||||
boolean focusedWindowChangeAllowed,
|
||||
long time,
|
||||
CausedFocusEvent.Cause cause)
|
||||
{
|
||||
return KfmAccessor.instance.shouldNativelyFocusHeavyweight(
|
||||
heavyweight, descendant, temporary, focusedWindowChangeAllowed,
|
||||
time, cause);
|
||||
}
|
||||
|
||||
public static void removeLastFocusRequest(Component heavyweight) {
|
||||
KfmAccessor.instance.removeLastFocusRequest(heavyweight);
|
||||
}
|
||||
|
||||
// WARNING: Don't call it on the Toolkit thread.
|
||||
public static boolean processSynchronousLightweightTransfer(Component heavyweight,
|
||||
Component descendant,
|
||||
boolean temporary,
|
||||
boolean focusedWindowChangeAllowed,
|
||||
long time)
|
||||
{
|
||||
return KfmAccessor.instance.processSynchronousLightweightTransfer(
|
||||
heavyweight, descendant, temporary, focusedWindowChangeAllowed,
|
||||
time);
|
||||
}
|
||||
}
|
||||
43
jdkSrc/jdk8/sun/awt/KeyboardFocusManagerPeerProvider.java
Normal file
43
jdkSrc/jdk8/sun/awt/KeyboardFocusManagerPeerProvider.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2012, 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;
|
||||
|
||||
import java.awt.peer.KeyboardFocusManagerPeer;
|
||||
|
||||
/**
|
||||
* {@link KeyboardFocusManagerPeerProvider} is required to be implemented by
|
||||
* the currently used {@link java.awt.Toolkit} instance. In order to initialize
|
||||
* {@link java.awt.KeyboardFocusManager}, a singleton instance of {@link KeyboardFocusManagerPeer}
|
||||
* is needed. To obtain that instance, the {@link #getKeyboardFocusManagerPeer}
|
||||
* method of the current toolkit is called.
|
||||
*/
|
||||
public interface KeyboardFocusManagerPeerProvider {
|
||||
|
||||
/**
|
||||
* Gets a singleton KeyboardFocusManagerPeer instance.
|
||||
*/
|
||||
KeyboardFocusManagerPeer getKeyboardFocusManagerPeer();
|
||||
}
|
||||
203
jdkSrc/jdk8/sun/awt/LightweightFrame.java
Normal file
203
jdkSrc/jdk8/sun/awt/LightweightFrame.java
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.MenuBar;
|
||||
import java.awt.MenuComponent;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.dnd.DragGestureEvent;
|
||||
import java.awt.dnd.DragGestureListener;
|
||||
import java.awt.dnd.DragGestureRecognizer;
|
||||
import java.awt.dnd.DragSource;
|
||||
import java.awt.dnd.DropTarget;
|
||||
import java.awt.dnd.InvalidDnDOperationException;
|
||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||
import java.awt.peer.FramePeer;
|
||||
|
||||
/**
|
||||
* The class provides basic functionality for a lightweight frame
|
||||
* implementation. A subclass is expected to provide painting to an
|
||||
* offscreen image and access to it. Thus it can be used for lightweight
|
||||
* embedding.
|
||||
*
|
||||
* @author Artem Ananiev
|
||||
* @author Anton Tarasov
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class LightweightFrame extends Frame {
|
||||
|
||||
/**
|
||||
* Constructs a new, initially invisible {@code LightweightFrame}
|
||||
* instance.
|
||||
*/
|
||||
public LightweightFrame() {
|
||||
setUndecorated(true);
|
||||
setResizable(true);
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks introspection of a parent window by this child.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
@Override public final Container getParent() { return null; }
|
||||
|
||||
@Override public Graphics getGraphics() { return null; }
|
||||
|
||||
@Override public final boolean isResizable() { return true; }
|
||||
|
||||
// Block modification of any frame attributes, since they aren't
|
||||
// applicable for a lightweight frame.
|
||||
|
||||
@Override public final void setTitle(String title) {}
|
||||
@Override public final void setIconImage(Image image) {}
|
||||
@Override public final void setIconImages(java.util.List<? extends Image> icons) {}
|
||||
@Override public final void setMenuBar(MenuBar mb) {}
|
||||
@Override public final void setResizable(boolean resizable) {}
|
||||
@Override public final void remove(MenuComponent m) {}
|
||||
@Override public final void toFront() {}
|
||||
@Override public final void toBack() {}
|
||||
|
||||
@Override public void addNotify() {
|
||||
synchronized (getTreeLock()) {
|
||||
if (getPeer() == null) {
|
||||
SunToolkit stk = (SunToolkit)Toolkit.getDefaultToolkit();
|
||||
try {
|
||||
setPeer(stk.createLightweightFrame(this));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
super.addNotify();
|
||||
}
|
||||
}
|
||||
|
||||
private void setPeer(final FramePeer p) {
|
||||
AWTAccessor.getComponentAccessor().setPeer(this, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the peer to emulate activation or deactivation of the
|
||||
* frame. Peers should override this method if they are to implement
|
||||
* this functionality.
|
||||
*
|
||||
* @param activate if <code>true</code>, activates the frame;
|
||||
* otherwise, deactivates the frame
|
||||
*/
|
||||
public void emulateActivation(boolean activate) {
|
||||
((FramePeer)getPeer()).emulateActivation(activate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates the focus grab action to the client (embedding) application.
|
||||
* The method is called by the AWT grab machinery.
|
||||
*
|
||||
* @see SunToolkit#grab(java.awt.Window)
|
||||
*/
|
||||
public abstract void grabFocus();
|
||||
|
||||
/**
|
||||
* Delegates the focus ungrab action to the client (embedding) application.
|
||||
* The method is called by the AWT grab machinery.
|
||||
*
|
||||
* @see SunToolkit#ungrab(java.awt.Window)
|
||||
*/
|
||||
public abstract void ungrabFocus();
|
||||
|
||||
/**
|
||||
* Returns the scale factor of this frame. The default value is 1.
|
||||
*
|
||||
* @return the scale factor
|
||||
* @see #notifyDisplayChanged(int)
|
||||
*/
|
||||
public abstract int getScaleFactor();
|
||||
|
||||
/**
|
||||
* Called when display of the hosted frame is changed.
|
||||
*
|
||||
* @param scaleFactor the scale factor
|
||||
*/
|
||||
public abstract void notifyDisplayChanged(int scaleFactor);
|
||||
|
||||
/**
|
||||
* Host window absolute bounds.
|
||||
*/
|
||||
private int hostX, hostY, hostW, hostH;
|
||||
|
||||
/**
|
||||
* Returns the absolute bounds of the host (embedding) window.
|
||||
*
|
||||
* @return the host window bounds
|
||||
*/
|
||||
public Rectangle getHostBounds() {
|
||||
if (hostX == 0 && hostY == 0 && hostW == 0 && hostH == 0) {
|
||||
// The client app is probably unaware of the setHostBounds.
|
||||
// A safe fall-back:
|
||||
return getBounds();
|
||||
}
|
||||
return new Rectangle(hostX, hostY, hostW, hostH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the absolute bounds of the host (embedding) window.
|
||||
*/
|
||||
public void setHostBounds(int x, int y, int w, int h) {
|
||||
hostX = x;
|
||||
hostY = y;
|
||||
hostW = w;
|
||||
hostH = h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a drag gesture recognizer for the lightweight frame.
|
||||
*/
|
||||
public abstract <T extends DragGestureRecognizer> T createDragGestureRecognizer(
|
||||
Class<T> abstractRecognizerClass,
|
||||
DragSource ds, Component c, int srcActions,
|
||||
DragGestureListener dgl);
|
||||
|
||||
/**
|
||||
* Create a drag source context peer for the lightweight frame.
|
||||
*/
|
||||
public abstract DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException;
|
||||
|
||||
/**
|
||||
* Adds a drop target to the lightweight frame.
|
||||
*/
|
||||
public abstract void addDropTarget(DropTarget dt);
|
||||
|
||||
/**
|
||||
* Removes a drop target from the lightweight frame.
|
||||
*/
|
||||
public abstract void removeDropTarget(DropTarget dt);
|
||||
}
|
||||
37
jdkSrc/jdk8/sun/awt/ModalExclude.java
Normal file
37
jdkSrc/jdk8/sun/awt/ModalExclude.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 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;
|
||||
|
||||
/**
|
||||
* Interface for identifying a component that will be excluded during
|
||||
* modal operations. Implementing this interface will ensure that the
|
||||
* component willl still receive it's events.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Joshua Outwater
|
||||
*/
|
||||
public interface ModalExclude {
|
||||
}
|
||||
61
jdkSrc/jdk8/sun/awt/ModalityEvent.java
Normal file
61
jdkSrc/jdk8/sun/awt/ModalityEvent.java
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, 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;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Event object describing changes in AWT modality
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class ModalityEvent extends AWTEvent implements ActiveEvent {
|
||||
|
||||
public static final int MODALITY_PUSHED = 1300;
|
||||
public static final int MODALITY_POPPED = 1301;
|
||||
|
||||
private ModalityListener listener;
|
||||
|
||||
public ModalityEvent(Object source, ModalityListener listener, int id) {
|
||||
super(source, id);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void dispatch() {
|
||||
switch(getID()) {
|
||||
case MODALITY_PUSHED:
|
||||
listener.modalityPushed(this);
|
||||
break;
|
||||
|
||||
case MODALITY_POPPED:
|
||||
listener.modalityPopped(this);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Invalid event id.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
42
jdkSrc/jdk8/sun/awt/ModalityListener.java
Normal file
42
jdkSrc/jdk8/sun/awt/ModalityListener.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, 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;
|
||||
|
||||
/**
|
||||
* Listener interface so Java Plug-in can be notified
|
||||
* of changes in AWT modality
|
||||
*/
|
||||
public interface ModalityListener {
|
||||
/**
|
||||
* Called by AWT when it enters a new level of modality
|
||||
*/
|
||||
public void modalityPushed(ModalityEvent ev);
|
||||
|
||||
/**
|
||||
* Called by AWT when it exits a level of modality
|
||||
*/
|
||||
public void modalityPopped(ModalityEvent ev);
|
||||
}
|
||||
62
jdkSrc/jdk8/sun/awt/Mutex.java
Normal file
62
jdkSrc/jdk8/sun/awt/Mutex.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 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;
|
||||
|
||||
public class Mutex {
|
||||
private boolean locked;
|
||||
private Thread owner;
|
||||
|
||||
public synchronized void lock() {
|
||||
if (locked && Thread.currentThread() == owner) {
|
||||
throw new IllegalMonitorStateException();
|
||||
}
|
||||
do {
|
||||
if (!locked) {
|
||||
locked = true;
|
||||
owner = Thread.currentThread();
|
||||
} else {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
// try again
|
||||
}
|
||||
}
|
||||
} while (owner != Thread.currentThread());
|
||||
}
|
||||
|
||||
public synchronized void unlock() {
|
||||
if (Thread.currentThread() != owner) {
|
||||
throw new IllegalMonitorStateException();
|
||||
}
|
||||
owner = null;
|
||||
locked = false;
|
||||
notify();
|
||||
}
|
||||
|
||||
protected boolean isOwned() {
|
||||
return (locked && Thread.currentThread() == owner);
|
||||
}
|
||||
}
|
||||
64
jdkSrc/jdk8/sun/awt/NativeLibLoader.java
Normal file
64
jdkSrc/jdk8/sun/awt/NativeLibLoader.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, 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;
|
||||
|
||||
class NativeLibLoader {
|
||||
|
||||
/**
|
||||
* This is copied from java.awt.Toolkit since we need the library
|
||||
* loaded in sun.awt.image also:
|
||||
*
|
||||
* WARNING: This is a temporary workaround for a problem in the
|
||||
* way the AWT loads native libraries. A number of classes in this
|
||||
* package (sun.awt.image) have a native method, initIDs(),
|
||||
* which initializes
|
||||
* the JNI field and method ids used in the native portion of
|
||||
* their implementation.
|
||||
*
|
||||
* Since the use and storage of these ids is done by the
|
||||
* implementation libraries, the implementation of these method is
|
||||
* provided by the particular AWT implementations
|
||||
* (i.e. "Toolkit"s/Peer), such as Motif, Win32 or Tiny. The
|
||||
* problem is that this means that the native libraries must be
|
||||
* loaded by the java.* classes, which do not necessarily know the
|
||||
* names of the libraries to load. A better way of doing this
|
||||
* would be to provide a separate library which defines java.awt.*
|
||||
* initIDs, and exports the relevant symbols out to the
|
||||
* implementation libraries.
|
||||
*
|
||||
* For now, we know it's done by the implementation, and we assume
|
||||
* that the name of the library is "awt". -br.
|
||||
*/
|
||||
static void loadLibraries() {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("awt");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
308
jdkSrc/jdk8/sun/awt/NullComponentPeer.java
Normal file
308
jdkSrc/jdk8/sun/awt/NullComponentPeer.java
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.BufferCapabilities;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.MenuBar;
|
||||
import java.awt.Point;
|
||||
import java.awt.Event;
|
||||
import java.awt.event.PaintEvent;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.awt.image.VolatileImage;
|
||||
import java.awt.peer.CanvasPeer;
|
||||
import java.awt.peer.LightweightPeer;
|
||||
import java.awt.peer.PanelPeer;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
import java.awt.peer.ContainerPeer;
|
||||
import java.awt.Rectangle;
|
||||
import sun.java2d.pipe.Region;
|
||||
|
||||
|
||||
/**
|
||||
* Implements the LightweightPeer interface for use in lightweight components
|
||||
* that have no native window associated with them. This gets created by
|
||||
* default in Component so that Component and Container can be directly
|
||||
* extended to create useful components written entirely in java. These
|
||||
* components must be hosted somewhere higher up in the component tree by a
|
||||
* native container (such as a Frame).
|
||||
*
|
||||
* This implementation provides no useful semantics and serves only as a
|
||||
* marker. One could provide alternative implementations in java that do
|
||||
* something useful for some of the other peer interfaces to minimize the
|
||||
* native code.
|
||||
*
|
||||
* This was renamed from java.awt.LightweightPeer (a horrible and confusing
|
||||
* name) and moved from java.awt.Toolkit into sun.awt as a public class in
|
||||
* its own file.
|
||||
*
|
||||
* @author Timothy Prinzing
|
||||
* @author Michael Martak
|
||||
*/
|
||||
|
||||
public class NullComponentPeer implements LightweightPeer,
|
||||
CanvasPeer, PanelPeer {
|
||||
|
||||
public boolean isObscured() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canDetermineObscurity() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFocusable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setVisible(boolean b) {
|
||||
}
|
||||
|
||||
public void show() {
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
}
|
||||
|
||||
public void setEnabled(boolean b) {
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
}
|
||||
|
||||
public void repaint(long tm, int x, int y, int width, int height) {
|
||||
}
|
||||
|
||||
public void print(Graphics g) {
|
||||
}
|
||||
|
||||
public void setBounds(int x, int y, int width, int height, int op) {
|
||||
}
|
||||
|
||||
public void reshape(int x, int y, int width, int height) {
|
||||
}
|
||||
|
||||
public void coalescePaintEvent(PaintEvent e) {
|
||||
}
|
||||
|
||||
public boolean handleEvent(Event e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void handleEvent(java.awt.AWTEvent arg0) {
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(1,1);
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize() {
|
||||
return new Dimension(1,1);
|
||||
}
|
||||
|
||||
public ColorModel getColorModel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Graphics getGraphics() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public GraphicsConfiguration getGraphicsConfiguration() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public FontMetrics getFontMetrics(Font font) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
// no native code
|
||||
}
|
||||
|
||||
public void setForeground(Color c) {
|
||||
}
|
||||
|
||||
public void setBackground(Color c) {
|
||||
}
|
||||
|
||||
public void setFont(Font f) {
|
||||
}
|
||||
|
||||
public void updateCursorImmediately() {
|
||||
}
|
||||
|
||||
public void setCursor(Cursor cursor) {
|
||||
}
|
||||
|
||||
public boolean requestFocus
|
||||
(Component lightweightChild, boolean temporary,
|
||||
boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Image createImage(ImageProducer producer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Image createImage(int width, int height) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean prepareImage(Image img, int w, int h, ImageObserver o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int checkImage(Image img, int w, int h, ImageObserver o) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Dimension preferredSize() {
|
||||
return getPreferredSize();
|
||||
}
|
||||
|
||||
public Dimension minimumSize() {
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
public Point getLocationOnScreen() {
|
||||
return new Point(0,0);
|
||||
}
|
||||
|
||||
public Insets getInsets() {
|
||||
return insets();
|
||||
}
|
||||
|
||||
public void beginValidate() {
|
||||
}
|
||||
|
||||
public void endValidate() {
|
||||
}
|
||||
|
||||
public Insets insets() {
|
||||
return new Insets(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
public boolean isPaintPending() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean handlesWheelScrolling() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public VolatileImage createVolatileImage(int width, int height) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void beginLayout() {
|
||||
}
|
||||
|
||||
public void endLayout() {
|
||||
}
|
||||
|
||||
public void createBuffers(int numBuffers, BufferCapabilities caps)
|
||||
throws AWTException {
|
||||
throw new AWTException(
|
||||
"Page-flipping is not allowed on a lightweight component");
|
||||
}
|
||||
public Image getBackBuffer() {
|
||||
throw new IllegalStateException(
|
||||
"Page-flipping is not allowed on a lightweight component");
|
||||
}
|
||||
public void flip(int x1, int y1, int x2, int y2,
|
||||
BufferCapabilities.FlipContents flipAction)
|
||||
{
|
||||
throw new IllegalStateException(
|
||||
"Page-flipping is not allowed on a lightweight component");
|
||||
}
|
||||
public void destroyBuffers() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.peer.ComponentPeer#isReparentSupported
|
||||
*/
|
||||
public boolean isReparentSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.peer.ComponentPeer#reparent
|
||||
*/
|
||||
public void reparent(ContainerPeer newNativeParent) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void layout() {
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
return new Rectangle(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies the shape to the native component window.
|
||||
* @since 1.7
|
||||
*/
|
||||
public void applyShape(Region shape) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Lowers this component at the bottom of the above HW peer. If the above parameter
|
||||
* is null then the method places this component at the top of the Z-order.
|
||||
*/
|
||||
public void setZOrder(ComponentPeer above) {
|
||||
}
|
||||
|
||||
public boolean updateGraphicsData(GraphicsConfiguration gc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public GraphicsConfiguration getAppropriateGraphicsConfiguration(
|
||||
GraphicsConfiguration gc)
|
||||
{
|
||||
return gc;
|
||||
}
|
||||
}
|
||||
189
jdkSrc/jdk8/sun/awt/OSInfo.java
Normal file
189
jdkSrc/jdk8/sun/awt/OSInfo.java
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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;
|
||||
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static sun.awt.OSInfo.OSType.*;
|
||||
|
||||
/**
|
||||
* @author Pavel Porvatov
|
||||
*/
|
||||
public class OSInfo {
|
||||
public static enum OSType {
|
||||
WINDOWS,
|
||||
LINUX,
|
||||
SOLARIS,
|
||||
MACOSX,
|
||||
UNKNOWN
|
||||
}
|
||||
|
||||
/*
|
||||
The map windowsVersionMap must contain all windows version constants except WINDOWS_UNKNOWN,
|
||||
and so the method getWindowsVersion() will return the constant for known OS.
|
||||
It allows compare objects by "==" instead of "equals".
|
||||
*/
|
||||
public static final WindowsVersion WINDOWS_UNKNOWN = new WindowsVersion(-1, -1);
|
||||
public static final WindowsVersion WINDOWS_95 = new WindowsVersion(4, 0);
|
||||
public static final WindowsVersion WINDOWS_98 = new WindowsVersion(4, 10);
|
||||
public static final WindowsVersion WINDOWS_ME = new WindowsVersion(4, 90);
|
||||
public static final WindowsVersion WINDOWS_2000 = new WindowsVersion(5, 0);
|
||||
public static final WindowsVersion WINDOWS_XP = new WindowsVersion(5, 1);
|
||||
public static final WindowsVersion WINDOWS_2003 = new WindowsVersion(5, 2);
|
||||
public static final WindowsVersion WINDOWS_VISTA = new WindowsVersion(6, 0);
|
||||
|
||||
private static final String OS_NAME = "os.name";
|
||||
private static final String OS_VERSION = "os.version";
|
||||
|
||||
private final static Map<String, WindowsVersion> windowsVersionMap = new HashMap<String, OSInfo.WindowsVersion>();
|
||||
|
||||
static {
|
||||
windowsVersionMap.put(WINDOWS_95.toString(), WINDOWS_95);
|
||||
windowsVersionMap.put(WINDOWS_98.toString(), WINDOWS_98);
|
||||
windowsVersionMap.put(WINDOWS_ME.toString(), WINDOWS_ME);
|
||||
windowsVersionMap.put(WINDOWS_2000.toString(), WINDOWS_2000);
|
||||
windowsVersionMap.put(WINDOWS_XP.toString(), WINDOWS_XP);
|
||||
windowsVersionMap.put(WINDOWS_2003.toString(), WINDOWS_2003);
|
||||
windowsVersionMap.put(WINDOWS_VISTA.toString(), WINDOWS_VISTA);
|
||||
}
|
||||
|
||||
private static final PrivilegedAction<OSType> osTypeAction = new PrivilegedAction<OSType>() {
|
||||
public OSType run() {
|
||||
return getOSType();
|
||||
}
|
||||
};
|
||||
|
||||
private OSInfo() {
|
||||
// Don't allow to create instances
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns type of operating system.
|
||||
*/
|
||||
public static OSType getOSType() throws SecurityException {
|
||||
String osName = System.getProperty(OS_NAME);
|
||||
|
||||
if (osName != null) {
|
||||
if (osName.contains("Windows")) {
|
||||
return WINDOWS;
|
||||
}
|
||||
|
||||
if (osName.contains("Linux")) {
|
||||
return LINUX;
|
||||
}
|
||||
|
||||
if (osName.contains("Solaris") || osName.contains("SunOS")) {
|
||||
return SOLARIS;
|
||||
}
|
||||
|
||||
if (osName.contains("OS X")) {
|
||||
return MACOSX;
|
||||
}
|
||||
|
||||
// determine another OS here
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
public static PrivilegedAction<OSType> getOSTypeAction() {
|
||||
return osTypeAction;
|
||||
}
|
||||
|
||||
public static WindowsVersion getWindowsVersion() throws SecurityException {
|
||||
String osVersion = System.getProperty(OS_VERSION);
|
||||
|
||||
if (osVersion == null) {
|
||||
return WINDOWS_UNKNOWN;
|
||||
}
|
||||
|
||||
synchronized (windowsVersionMap) {
|
||||
WindowsVersion result = windowsVersionMap.get(osVersion);
|
||||
|
||||
if (result == null) {
|
||||
// Try parse version and put object into windowsVersionMap
|
||||
String[] arr = osVersion.split("\\.");
|
||||
|
||||
if (arr.length == 2) {
|
||||
try {
|
||||
result = new WindowsVersion(Integer.parseInt(arr[0]), Integer.parseInt(arr[1]));
|
||||
} catch (NumberFormatException e) {
|
||||
return WINDOWS_UNKNOWN;
|
||||
}
|
||||
} else {
|
||||
return WINDOWS_UNKNOWN;
|
||||
}
|
||||
|
||||
windowsVersionMap.put(osVersion, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WindowsVersion implements Comparable<WindowsVersion> {
|
||||
private final int major;
|
||||
|
||||
private final int minor;
|
||||
|
||||
private WindowsVersion(int major, int minor) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
}
|
||||
|
||||
public int getMajor() {
|
||||
return major;
|
||||
}
|
||||
|
||||
public int getMinor() {
|
||||
return minor;
|
||||
}
|
||||
|
||||
public int compareTo(WindowsVersion o) {
|
||||
int result = major - o.getMajor();
|
||||
|
||||
if (result == 0) {
|
||||
result = minor - o.getMinor();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof WindowsVersion && compareTo((WindowsVersion) obj) == 0;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 31 * major + minor;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return major + "." + minor;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
jdkSrc/jdk8/sun/awt/OverrideNativeWindowHandle.java
Normal file
41
jdkSrc/jdk8/sun/awt/OverrideNativeWindowHandle.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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;
|
||||
|
||||
/**
|
||||
* Used for replacing window owner with another non-Swing window.
|
||||
* It is useful in case of JavaFX-Swing interop:
|
||||
* it helps to keep Swing dialogs above its owner(JavaFX stage).
|
||||
*/
|
||||
|
||||
public interface OverrideNativeWindowHandle {
|
||||
|
||||
/**
|
||||
* Replaces an owner window with a window with provided handle.
|
||||
* @param handle native window handle
|
||||
*/
|
||||
void overrideWindowHandle(final long handle);
|
||||
}
|
||||
104
jdkSrc/jdk8/sun/awt/PaintEventDispatcher.java
Normal file
104
jdkSrc/jdk8/sun/awt/PaintEventDispatcher.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, 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;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.PaintEvent;
|
||||
|
||||
/**
|
||||
* PaintEventDispatcher is responsible for dispatching PaintEvents. There
|
||||
* can be only one PaintEventDispatcher active at a particular time.
|
||||
*
|
||||
*/
|
||||
public class PaintEventDispatcher {
|
||||
/**
|
||||
* Singleton dispatcher.
|
||||
*/
|
||||
private static PaintEventDispatcher dispatcher;
|
||||
|
||||
/**
|
||||
* Sets the current <code>PaintEventDispatcher</code>.
|
||||
*
|
||||
* @param dispatcher PaintEventDispatcher
|
||||
*/
|
||||
public static void setPaintEventDispatcher(
|
||||
PaintEventDispatcher dispatcher) {
|
||||
synchronized(PaintEventDispatcher.class) {
|
||||
PaintEventDispatcher.dispatcher = dispatcher;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently active <code>PaintEventDispatcher</code>. This
|
||||
* will never return null.
|
||||
*
|
||||
* @return PaintEventDispatcher
|
||||
*/
|
||||
public static PaintEventDispatcher getPaintEventDispatcher() {
|
||||
synchronized(PaintEventDispatcher.class) {
|
||||
if (dispatcher == null) {
|
||||
dispatcher = new PaintEventDispatcher();
|
||||
}
|
||||
return dispatcher;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the <code>PaintEvent</code> that should be
|
||||
* dispatched for the specified component. If this returns null
|
||||
* no <code>PaintEvent</code> is dispatched.
|
||||
* <p>
|
||||
* <b>WARNING:</b> This is invoked from the native thread, be careful
|
||||
* what methods you end up invoking here.
|
||||
*/
|
||||
public PaintEvent createPaintEvent(Component target, int x, int y, int w,
|
||||
int h) {
|
||||
|
||||
return new PaintEvent(target, PaintEvent.PAINT,
|
||||
new Rectangle(x, y, w, h));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a native background erase should be done for
|
||||
* the specified Component.
|
||||
*/
|
||||
public boolean shouldDoNativeBackgroundErase(Component c) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked from the toolkit thread when the surface
|
||||
* data of the component needs to be replaced. The method run() of
|
||||
* the Runnable argument performs surface data replacing, run()
|
||||
* should be invoked on the EDT of this component's AppContext.
|
||||
* Returns true if the Runnable has been enqueued to be invoked
|
||||
* on the EDT.
|
||||
* (Fix 6255371.)
|
||||
*/
|
||||
public boolean queueSurfaceDataReplacing(Component c, Runnable r) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
56
jdkSrc/jdk8/sun/awt/PeerEvent.java
Normal file
56
jdkSrc/jdk8/sun/awt/PeerEvent.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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;
|
||||
|
||||
import java.awt.event.InvocationEvent;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class PeerEvent extends InvocationEvent {
|
||||
|
||||
public static final long PRIORITY_EVENT = 0x01;
|
||||
public static final long ULTIMATE_PRIORITY_EVENT = 0x02;
|
||||
public static final long LOW_PRIORITY_EVENT = 0x04;
|
||||
|
||||
private long flags;
|
||||
|
||||
public PeerEvent(Object source, Runnable runnable, long flags) {
|
||||
this(source, runnable, null, false, flags);
|
||||
}
|
||||
|
||||
public PeerEvent(Object source, Runnable runnable, Object notifier,
|
||||
boolean catchExceptions, long flags) {
|
||||
super(source, runnable, notifier, catchExceptions);
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public long getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public PeerEvent coalesceEvents(PeerEvent newEvent) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
440
jdkSrc/jdk8/sun/awt/PlatformFont.java
Normal file
440
jdkSrc/jdk8/sun/awt/PlatformFont.java
Normal file
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2010, 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;
|
||||
|
||||
import java.awt.peer.FontPeer;
|
||||
import java.util.Locale;
|
||||
import java.util.Vector;
|
||||
import sun.font.SunFontManager;
|
||||
import sun.java2d.FontSupport;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public abstract class PlatformFont implements FontPeer {
|
||||
|
||||
static {
|
||||
NativeLibLoader.loadLibraries();
|
||||
initIDs();
|
||||
}
|
||||
|
||||
protected FontDescriptor[] componentFonts;
|
||||
protected char defaultChar;
|
||||
protected FontConfiguration fontConfig;
|
||||
|
||||
protected FontDescriptor defaultFont;
|
||||
|
||||
protected String familyName;
|
||||
|
||||
private Object[] fontCache;
|
||||
|
||||
// Maybe this should be a property that is set based
|
||||
// on the locale?
|
||||
protected static int FONTCACHESIZE = 256;
|
||||
protected static int FONTCACHEMASK = PlatformFont.FONTCACHESIZE - 1;
|
||||
protected static String osVersion;
|
||||
|
||||
public PlatformFont(String name, int style){
|
||||
SunFontManager sfm = SunFontManager.getInstance();
|
||||
if (sfm instanceof FontSupport) {
|
||||
fontConfig = ((FontSupport)sfm).getFontConfiguration();
|
||||
}
|
||||
if (fontConfig == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// map given font name to a valid logical font family name
|
||||
familyName = name.toLowerCase(Locale.ENGLISH);
|
||||
if (!FontConfiguration.isLogicalFontFamilyName(familyName)) {
|
||||
familyName = fontConfig.getFallbackFamilyName(familyName, "sansserif");
|
||||
}
|
||||
|
||||
componentFonts = fontConfig.getFontDescriptors(familyName, style);
|
||||
|
||||
// search default character
|
||||
//
|
||||
char missingGlyphCharacter = getMissingGlyphCharacter();
|
||||
|
||||
defaultChar = '?';
|
||||
if (componentFonts.length > 0)
|
||||
defaultFont = componentFonts[0];
|
||||
|
||||
for (int i = 0; i < componentFonts.length; i++){
|
||||
if (componentFonts[i].isExcluded(missingGlyphCharacter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (componentFonts[i].encoder.canEncode(missingGlyphCharacter)) {
|
||||
defaultFont = componentFonts[i];
|
||||
defaultChar = missingGlyphCharacter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character that should be rendered when a glyph
|
||||
* is missing.
|
||||
*/
|
||||
protected abstract char getMissingGlyphCharacter();
|
||||
|
||||
/**
|
||||
* make a array of CharsetString with given String.
|
||||
*/
|
||||
public CharsetString[] makeMultiCharsetString(String str){
|
||||
return makeMultiCharsetString(str.toCharArray(), 0, str.length(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* make a array of CharsetString with given String.
|
||||
*/
|
||||
public CharsetString[] makeMultiCharsetString(String str, boolean allowdefault){
|
||||
return makeMultiCharsetString(str.toCharArray(), 0, str.length(), allowdefault);
|
||||
}
|
||||
|
||||
/**
|
||||
* make a array of CharsetString with given char array.
|
||||
* @param str The char array to convert.
|
||||
* @param offset offset of first character of interest
|
||||
* @param len number of characters to convert
|
||||
*/
|
||||
public CharsetString[] makeMultiCharsetString(char str[], int offset, int len) {
|
||||
return makeMultiCharsetString(str, offset, len, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* make a array of CharsetString with given char array.
|
||||
* @param str The char array to convert.
|
||||
* @param offset offset of first character of interest
|
||||
* @param len number of characters to convert
|
||||
* @param allowDefault whether to allow the default char.
|
||||
* Setting this to true overloads the meaning of this method to
|
||||
* return non-null only if all chars can be converted.
|
||||
* @return array of CharsetString or if allowDefault is false and any
|
||||
* of the returned chars would have been converted to a default char,
|
||||
* then return null.
|
||||
* This is used to choose alternative means of displaying the text.
|
||||
*/
|
||||
public CharsetString[] makeMultiCharsetString(char str[], int offset, int len,
|
||||
boolean allowDefault) {
|
||||
|
||||
if (len < 1) {
|
||||
return new CharsetString[0];
|
||||
}
|
||||
Vector mcs = null;
|
||||
char[] tmpStr = new char[len];
|
||||
char tmpChar = defaultChar;
|
||||
boolean encoded = false;
|
||||
|
||||
FontDescriptor currentFont = defaultFont;
|
||||
|
||||
|
||||
for (int i = 0; i < componentFonts.length; i++) {
|
||||
if (componentFonts[i].isExcluded(str[offset])){
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Need "encoded" variable to distinguish the case when
|
||||
* the default char is the same as the encoded char.
|
||||
* The defaultChar on Linux is '?' so it is needed there.
|
||||
*/
|
||||
if (componentFonts[i].encoder.canEncode(str[offset])){
|
||||
currentFont = componentFonts[i];
|
||||
tmpChar = str[offset];
|
||||
encoded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allowDefault && !encoded) {
|
||||
return null;
|
||||
} else {
|
||||
tmpStr[0] = tmpChar;
|
||||
}
|
||||
|
||||
int lastIndex = 0;
|
||||
for (int i = 1; i < len; i++){
|
||||
char ch = str[offset + i];
|
||||
FontDescriptor fd = defaultFont;
|
||||
tmpChar = defaultChar;
|
||||
encoded = false;
|
||||
for (int j = 0; j < componentFonts.length; j++){
|
||||
if (componentFonts[j].isExcluded(ch)){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (componentFonts[j].encoder.canEncode(ch)){
|
||||
fd = componentFonts[j];
|
||||
tmpChar = ch;
|
||||
encoded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allowDefault && !encoded) {
|
||||
return null;
|
||||
} else {
|
||||
tmpStr[i] = tmpChar;
|
||||
}
|
||||
if (currentFont != fd){
|
||||
if (mcs == null) {
|
||||
mcs = new Vector(3);
|
||||
}
|
||||
mcs.addElement(new CharsetString(tmpStr, lastIndex,
|
||||
i-lastIndex, currentFont));
|
||||
currentFont = fd;
|
||||
fd = defaultFont;
|
||||
lastIndex = i;
|
||||
}
|
||||
}
|
||||
CharsetString[] result;
|
||||
CharsetString cs = new CharsetString(tmpStr, lastIndex,
|
||||
len-lastIndex, currentFont);
|
||||
if (mcs == null) {
|
||||
result = new CharsetString[1];
|
||||
result[0] = cs;
|
||||
} else {
|
||||
mcs.addElement(cs);
|
||||
result = new CharsetString[mcs.size()];
|
||||
for (int i = 0; i < mcs.size(); i++){
|
||||
result[i] = (CharsetString)mcs.elementAt(i);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is it possible that this font's metrics require the multi-font calls?
|
||||
* This might be true, for example, if the font supports kerning.
|
||||
**/
|
||||
public boolean mightHaveMultiFontMetrics() {
|
||||
return fontConfig != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized fast path string conversion for AWT.
|
||||
*/
|
||||
public Object[] makeConvertedMultiFontString(String str)
|
||||
{
|
||||
return makeConvertedMultiFontChars(str.toCharArray(),0,str.length());
|
||||
}
|
||||
|
||||
public Object[] makeConvertedMultiFontChars(char[] data,
|
||||
int start, int len)
|
||||
{
|
||||
Object[] result = new Object[2];
|
||||
Object[] workingCache;
|
||||
byte[] convertedData = null;
|
||||
int stringIndex = start;
|
||||
int convertedDataIndex = 0;
|
||||
int resultIndex = 0;
|
||||
int cacheIndex;
|
||||
FontDescriptor currentFontDescriptor = null;
|
||||
FontDescriptor lastFontDescriptor = null;
|
||||
char currentDefaultChar;
|
||||
PlatformFontCache theChar;
|
||||
|
||||
// Simple bounds check
|
||||
int end = start + len;
|
||||
if (start < 0 || end > data.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
if(stringIndex >= end) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// coversion loop
|
||||
while(stringIndex < end)
|
||||
{
|
||||
currentDefaultChar = data[stringIndex];
|
||||
|
||||
// Note that cache sizes must be a power of two!
|
||||
cacheIndex = (int)(currentDefaultChar & this.FONTCACHEMASK);
|
||||
|
||||
theChar = (PlatformFontCache)getFontCache()[cacheIndex];
|
||||
|
||||
// Is the unicode char we want cached?
|
||||
if(theChar == null || theChar.uniChar != currentDefaultChar)
|
||||
{
|
||||
/* find a converter that can convert the current character */
|
||||
currentFontDescriptor = defaultFont;
|
||||
currentDefaultChar = defaultChar;
|
||||
char ch = (char)data[stringIndex];
|
||||
int componentCount = componentFonts.length;
|
||||
|
||||
for (int j = 0; j < componentCount; j++) {
|
||||
FontDescriptor fontDescriptor = componentFonts[j];
|
||||
|
||||
fontDescriptor.encoder.reset();
|
||||
//fontDescriptor.encoder.onUnmappleCharacterAction(...);
|
||||
|
||||
if (fontDescriptor.isExcluded(ch)) {
|
||||
continue;
|
||||
}
|
||||
if (fontDescriptor.encoder.canEncode(ch)) {
|
||||
currentFontDescriptor = fontDescriptor;
|
||||
currentDefaultChar = ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
char[] input = new char[1];
|
||||
input[0] = currentDefaultChar;
|
||||
|
||||
theChar = new PlatformFontCache();
|
||||
if (currentFontDescriptor.useUnicode()) {
|
||||
/*
|
||||
currentFontDescriptor.unicodeEncoder.encode(CharBuffer.wrap(input),
|
||||
theChar.bb,
|
||||
true);
|
||||
*/
|
||||
if (currentFontDescriptor.isLE) {
|
||||
theChar.bb.put((byte)(input[0] & 0xff));
|
||||
theChar.bb.put((byte)(input[0] >>8));
|
||||
} else {
|
||||
theChar.bb.put((byte)(input[0] >> 8));
|
||||
theChar.bb.put((byte)(input[0] & 0xff));
|
||||
}
|
||||
}
|
||||
else {
|
||||
currentFontDescriptor.encoder.encode(CharBuffer.wrap(input),
|
||||
theChar.bb,
|
||||
true);
|
||||
}
|
||||
theChar.fontDescriptor = currentFontDescriptor;
|
||||
theChar.uniChar = data[stringIndex];
|
||||
getFontCache()[cacheIndex] = theChar;
|
||||
} catch(Exception e){
|
||||
// Should never happen!
|
||||
System.err.println(e);
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if we've changed fonts.
|
||||
if(lastFontDescriptor != theChar.fontDescriptor) {
|
||||
if(lastFontDescriptor != null) {
|
||||
result[resultIndex++] = lastFontDescriptor;
|
||||
result[resultIndex++] = convertedData;
|
||||
// Add the size to the converted data field.
|
||||
if(convertedData != null) {
|
||||
convertedDataIndex -= 4;
|
||||
convertedData[0] = (byte)(convertedDataIndex >> 24);
|
||||
convertedData[1] = (byte)(convertedDataIndex >> 16);
|
||||
convertedData[2] = (byte)(convertedDataIndex >> 8);
|
||||
convertedData[3] = (byte)convertedDataIndex;
|
||||
}
|
||||
|
||||
if(resultIndex >= result.length) {
|
||||
Object[] newResult = new Object[result.length * 2];
|
||||
|
||||
System.arraycopy(result, 0, newResult, 0,
|
||||
result.length);
|
||||
result = newResult;
|
||||
}
|
||||
}
|
||||
|
||||
if (theChar.fontDescriptor.useUnicode()) {
|
||||
convertedData = new byte[(end - stringIndex + 1) *
|
||||
(int)theChar.fontDescriptor.unicodeEncoder.maxBytesPerChar()
|
||||
+ 4];
|
||||
}
|
||||
else {
|
||||
convertedData = new byte[(end - stringIndex + 1) *
|
||||
(int)theChar.fontDescriptor.encoder.maxBytesPerChar()
|
||||
+ 4];
|
||||
}
|
||||
|
||||
convertedDataIndex = 4;
|
||||
|
||||
lastFontDescriptor = theChar.fontDescriptor;
|
||||
}
|
||||
|
||||
byte[] ba = theChar.bb.array();
|
||||
int size = theChar.bb.position();
|
||||
if(size == 1) {
|
||||
convertedData[convertedDataIndex++] = ba[0];
|
||||
}
|
||||
else if(size == 2) {
|
||||
convertedData[convertedDataIndex++] = ba[0];
|
||||
convertedData[convertedDataIndex++] = ba[1];
|
||||
} else if(size == 3) {
|
||||
convertedData[convertedDataIndex++] = ba[0];
|
||||
convertedData[convertedDataIndex++] = ba[1];
|
||||
convertedData[convertedDataIndex++] = ba[2];
|
||||
} else if(size == 4) {
|
||||
convertedData[convertedDataIndex++] = ba[0];
|
||||
convertedData[convertedDataIndex++] = ba[1];
|
||||
convertedData[convertedDataIndex++] = ba[2];
|
||||
convertedData[convertedDataIndex++] = ba[3];
|
||||
}
|
||||
stringIndex++;
|
||||
}
|
||||
|
||||
result[resultIndex++] = lastFontDescriptor;
|
||||
result[resultIndex] = convertedData;
|
||||
|
||||
// Add the size to the converted data field.
|
||||
if(convertedData != null) {
|
||||
convertedDataIndex -= 4;
|
||||
convertedData[0] = (byte)(convertedDataIndex >> 24);
|
||||
convertedData[1] = (byte)(convertedDataIndex >> 16);
|
||||
convertedData[2] = (byte)(convertedDataIndex >> 8);
|
||||
convertedData[3] = (byte)convertedDataIndex;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create fontCache on demand instead of during construction to
|
||||
* reduce overall memory consumption.
|
||||
*
|
||||
* This method is declared final so that its code can be inlined
|
||||
* by the compiler.
|
||||
*/
|
||||
protected final Object[] getFontCache() {
|
||||
// This method is not MT-safe by design. Since this is just a
|
||||
// cache anyways, it's okay if we occasionally allocate the array
|
||||
// twice or return an array which will be dereferenced and gced
|
||||
// right away.
|
||||
if (fontCache == null) {
|
||||
fontCache = new Object[this.FONTCACHESIZE];
|
||||
}
|
||||
|
||||
return fontCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize JNI field and method IDs
|
||||
*/
|
||||
private static native void initIDs();
|
||||
|
||||
class PlatformFontCache
|
||||
{
|
||||
char uniChar;
|
||||
FontDescriptor fontDescriptor;
|
||||
ByteBuffer bb = ByteBuffer.allocate(4);
|
||||
}
|
||||
}
|
||||
312
jdkSrc/jdk8/sun/awt/RepaintArea.java
Normal file
312
jdkSrc/jdk8/sun/awt/RepaintArea.java
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2007, 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;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.PaintEvent;
|
||||
|
||||
/**
|
||||
* The <code>RepaintArea</code> is a geometric construct created for the
|
||||
* purpose of holding the geometry of several coalesced paint events.
|
||||
* This geometry is accessed synchronously, although it is written such
|
||||
* that painting may still be executed asynchronously.
|
||||
*
|
||||
* @author Eric Hawkes
|
||||
* @since 1.3
|
||||
*/
|
||||
public class RepaintArea {
|
||||
|
||||
/**
|
||||
* Maximum ratio of bounding rectangle to benefit for which
|
||||
* both the vertical and horizontal unions are repainted.
|
||||
* For smaller ratios the whole bounding rectangle is repainted.
|
||||
* @see #paint
|
||||
*/
|
||||
private static final int MAX_BENEFIT_RATIO = 4;
|
||||
|
||||
private static final int HORIZONTAL = 0;
|
||||
private static final int VERTICAL = 1;
|
||||
private static final int UPDATE = 2;
|
||||
|
||||
private static final int RECT_COUNT = UPDATE + 1;
|
||||
|
||||
private Rectangle paintRects[] = new Rectangle[RECT_COUNT];
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new <code>RepaintArea</code>
|
||||
* @since 1.3
|
||||
*/
|
||||
public RepaintArea() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>RepaintArea</code> initialized to match
|
||||
* the values of the specified RepaintArea.
|
||||
*
|
||||
* @param ra the <code>RepaintArea</code> from which to copy initial
|
||||
* values to a newly constructed RepaintArea
|
||||
* @since 1.3
|
||||
*/
|
||||
private RepaintArea(RepaintArea ra) {
|
||||
// This constructor is private because it should only be called
|
||||
// from the cloneAndReset method
|
||||
for (int i = 0; i < RECT_COUNT; i++) {
|
||||
paintRects[i] = ra.paintRects[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a <code>Rectangle</code> to this <code>RepaintArea</code>.
|
||||
* PAINT Rectangles are divided into mostly vertical and mostly horizontal.
|
||||
* Each group is unioned together.
|
||||
* UPDATE Rectangles are unioned.
|
||||
*
|
||||
* @param r the specified <code>Rectangle</code>
|
||||
* @param id possible values PaintEvent.UPDATE or PaintEvent.PAINT
|
||||
* @since 1.3
|
||||
*/
|
||||
public synchronized void add(Rectangle r, int id) {
|
||||
// Make sure this new rectangle has positive dimensions
|
||||
if (r.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int addTo = UPDATE;
|
||||
if (id == PaintEvent.PAINT) {
|
||||
addTo = (r.width > r.height) ? HORIZONTAL : VERTICAL;
|
||||
}
|
||||
if (paintRects[addTo] != null) {
|
||||
paintRects[addTo].add(r);
|
||||
} else {
|
||||
paintRects[addTo] = new Rectangle(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>RepaintArea</code> with the same geometry as this
|
||||
* RepaintArea, then removes all of the geometry from this
|
||||
* RepaintArea and restores it to an empty RepaintArea.
|
||||
*
|
||||
* @return ra a new <code>RepaintArea</code> having the same geometry as
|
||||
* this RepaintArea.
|
||||
* @since 1.3
|
||||
*/
|
||||
private synchronized RepaintArea cloneAndReset() {
|
||||
RepaintArea ra = new RepaintArea(this);
|
||||
for (int i = 0; i < RECT_COUNT; i++) {
|
||||
paintRects[i] = null;
|
||||
}
|
||||
return ra;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
for (int i = 0; i < RECT_COUNT; i++) {
|
||||
if (paintRects[i] != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constrains the size of the repaint area to the passed in bounds.
|
||||
*/
|
||||
public synchronized void constrain(int x, int y, int w, int h) {
|
||||
for (int i = 0; i < RECT_COUNT; i++) {
|
||||
Rectangle rect = paintRects[i];
|
||||
if (rect != null) {
|
||||
if (rect.x < x) {
|
||||
rect.width -= (x - rect.x);
|
||||
rect.x = x;
|
||||
}
|
||||
if (rect.y < y) {
|
||||
rect.height -= (y - rect.y);
|
||||
rect.y = y;
|
||||
}
|
||||
int xDelta = rect.x + rect.width - x - w;
|
||||
if (xDelta > 0) {
|
||||
rect.width -= xDelta;
|
||||
}
|
||||
int yDelta = rect.y + rect.height - y - h;
|
||||
if (yDelta > 0) {
|
||||
rect.height -= yDelta;
|
||||
}
|
||||
if (rect.width <= 0 || rect.height <= 0) {
|
||||
paintRects[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the passed in region as not needing to be painted. It's possible
|
||||
* this will do nothing.
|
||||
*/
|
||||
public synchronized void subtract(int x, int y, int w, int h) {
|
||||
Rectangle subtract = new Rectangle(x, y, w, h);
|
||||
for (int i = 0; i < RECT_COUNT; i++) {
|
||||
if (subtract(paintRects[i], subtract)) {
|
||||
if (paintRects[i] != null && paintRects[i].isEmpty()) {
|
||||
paintRects[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes paint and update on target Component with optimal
|
||||
* rectangular clip region.
|
||||
* If PAINT bounding rectangle is less than
|
||||
* MAX_BENEFIT_RATIO times the benefit, then the vertical and horizontal unions are
|
||||
* painted separately. Otherwise the entire bounding rectangle is painted.
|
||||
*
|
||||
* @param target Component to <code>paint</code> or <code>update</code>
|
||||
* @since 1.4
|
||||
*/
|
||||
public void paint(Object target, boolean shouldClearRectBeforePaint) {
|
||||
Component comp = (Component)target;
|
||||
|
||||
if (isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!comp.isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RepaintArea ra = this.cloneAndReset();
|
||||
|
||||
if (!subtract(ra.paintRects[VERTICAL], ra.paintRects[HORIZONTAL])) {
|
||||
subtract(ra.paintRects[HORIZONTAL], ra.paintRects[VERTICAL]);
|
||||
}
|
||||
|
||||
if (ra.paintRects[HORIZONTAL] != null && ra.paintRects[VERTICAL] != null) {
|
||||
Rectangle paintRect = ra.paintRects[HORIZONTAL].union(ra.paintRects[VERTICAL]);
|
||||
int square = paintRect.width * paintRect.height;
|
||||
int benefit = square - ra.paintRects[HORIZONTAL].width
|
||||
* ra.paintRects[HORIZONTAL].height - ra.paintRects[VERTICAL].width
|
||||
* ra.paintRects[VERTICAL].height;
|
||||
// if benefit is comparable with bounding box
|
||||
if (MAX_BENEFIT_RATIO * benefit < square) {
|
||||
ra.paintRects[HORIZONTAL] = paintRect;
|
||||
ra.paintRects[VERTICAL] = null;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < paintRects.length; i++) {
|
||||
if (ra.paintRects[i] != null
|
||||
&& !ra.paintRects[i].isEmpty())
|
||||
{
|
||||
// Should use separate Graphics for each paint() call,
|
||||
// since paint() can change Graphics state for next call.
|
||||
Graphics g = comp.getGraphics();
|
||||
if (g != null) {
|
||||
try {
|
||||
g.setClip(ra.paintRects[i]);
|
||||
if (i == UPDATE) {
|
||||
updateComponent(comp, g);
|
||||
} else {
|
||||
if (shouldClearRectBeforePaint) {
|
||||
g.clearRect( ra.paintRects[i].x,
|
||||
ra.paintRects[i].y,
|
||||
ra.paintRects[i].width,
|
||||
ra.paintRects[i].height);
|
||||
}
|
||||
paintComponent(comp, g);
|
||||
}
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls <code>Component.update(Graphics)</code> with given Graphics.
|
||||
*/
|
||||
protected void updateComponent(Component comp, Graphics g) {
|
||||
if (comp != null) {
|
||||
comp.update(g);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls <code>Component.paint(Graphics)</code> with given Graphics.
|
||||
*/
|
||||
protected void paintComponent(Component comp, Graphics g) {
|
||||
if (comp != null) {
|
||||
comp.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts subtr from rect. If the result is rectangle
|
||||
* changes rect and returns true. Otherwise false.
|
||||
*/
|
||||
static boolean subtract(Rectangle rect, Rectangle subtr) {
|
||||
if (rect == null || subtr == null) {
|
||||
return true;
|
||||
}
|
||||
Rectangle common = rect.intersection(subtr);
|
||||
if (common.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
if (rect.x == common.x && rect.y == common.y) {
|
||||
if (rect.width == common.width) {
|
||||
rect.y += common.height;
|
||||
rect.height -= common.height;
|
||||
return true;
|
||||
} else
|
||||
if (rect.height == common.height) {
|
||||
rect.x += common.width;
|
||||
rect.width -= common.width;
|
||||
return true;
|
||||
}
|
||||
} else
|
||||
if (rect.x + rect.width == common.x + common.width
|
||||
&& rect.y + rect.height == common.y + common.height)
|
||||
{
|
||||
if (rect.width == common.width) {
|
||||
rect.height -= common.height;
|
||||
return true;
|
||||
} else
|
||||
if (rect.height == common.height) {
|
||||
rect.width -= common.width;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + "[ horizontal=" + paintRects[0] +
|
||||
" vertical=" + paintRects[1] +
|
||||
" update=" + paintRects[2] + "]";
|
||||
}
|
||||
}
|
||||
34
jdkSrc/jdk8/sun/awt/RequestFocusController.java
Normal file
34
jdkSrc/jdk8/sun/awt/RequestFocusController.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 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;
|
||||
|
||||
import java.awt.Component;
|
||||
|
||||
public interface RequestFocusController
|
||||
{
|
||||
public boolean acceptRequestFocus(Component from, Component to,
|
||||
boolean temporary, boolean focusedWindowChangeAllowed,
|
||||
CausedFocusEvent.Cause cause);
|
||||
}
|
||||
187
jdkSrc/jdk8/sun/awt/ScrollPaneWheelScroller.java
Normal file
187
jdkSrc/jdk8/sun/awt/ScrollPaneWheelScroller.java
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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;
|
||||
|
||||
import java.awt.ScrollPane;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Adjustable;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
/*
|
||||
* ScrollPaneWheelScroller is a helper class for implmenenting mouse wheel
|
||||
* scrolling on a java.awt.ScrollPane. It contains only static methods.
|
||||
* No objects of this class may be instantiated, thus it is declared abstract.
|
||||
*/
|
||||
public abstract class ScrollPaneWheelScroller {
|
||||
|
||||
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.ScrollPaneWheelScroller");
|
||||
|
||||
private ScrollPaneWheelScroller() {}
|
||||
|
||||
/*
|
||||
* Called from ScrollPane.processMouseWheelEvent()
|
||||
*/
|
||||
public static void handleWheelScrolling(ScrollPane sp, MouseWheelEvent e) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer("x = " + e.getX() + ", y = " + e.getY() + ", src is " + e.getSource());
|
||||
}
|
||||
int increment = 0;
|
||||
|
||||
if (sp != null && e.getScrollAmount() != 0) {
|
||||
Adjustable adj = getAdjustableToScroll(sp);
|
||||
if (adj != null) {
|
||||
increment = getIncrementFromAdjustable(adj, e);
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer("increment from adjustable(" + adj.getClass() + ") : " + increment);
|
||||
}
|
||||
scrollAdjustable(adj, increment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a ScrollPane, determine which Scrollbar should be scrolled by the
|
||||
* mouse wheel, if any.
|
||||
*/
|
||||
public static Adjustable getAdjustableToScroll(ScrollPane sp) {
|
||||
int policy = sp.getScrollbarDisplayPolicy();
|
||||
|
||||
// if policy is display always or never, use vert
|
||||
if (policy == ScrollPane.SCROLLBARS_ALWAYS ||
|
||||
policy == ScrollPane.SCROLLBARS_NEVER) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer("using vertical scrolling due to scrollbar policy");
|
||||
}
|
||||
return sp.getVAdjustable();
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
Insets ins = sp.getInsets();
|
||||
int vertScrollWidth = sp.getVScrollbarWidth();
|
||||
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer("insets: l = " + ins.left + ", r = " + ins.right +
|
||||
", t = " + ins.top + ", b = " + ins.bottom);
|
||||
log.finer("vertScrollWidth = " + vertScrollWidth);
|
||||
}
|
||||
|
||||
// Check if scrollbar is showing by examining insets of the
|
||||
// ScrollPane
|
||||
if (ins.right >= vertScrollWidth) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer("using vertical scrolling because scrollbar is present");
|
||||
}
|
||||
return sp.getVAdjustable();
|
||||
}
|
||||
else {
|
||||
int horizScrollHeight = sp.getHScrollbarHeight();
|
||||
if (ins.bottom >= horizScrollHeight) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer("using horiz scrolling because scrollbar is present");
|
||||
}
|
||||
return sp.getHAdjustable();
|
||||
}
|
||||
else {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer("using NO scrollbar becsause neither is present");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Given the info in a MouseWheelEvent and an Adjustable to scroll, return
|
||||
* the amount by which the Adjustable should be adjusted. This value may
|
||||
* be positive or negative.
|
||||
*/
|
||||
public static int getIncrementFromAdjustable(Adjustable adj,
|
||||
MouseWheelEvent e) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
if (adj == null) {
|
||||
log.fine("Assertion (adj != null) failed");
|
||||
}
|
||||
}
|
||||
|
||||
int increment = 0;
|
||||
|
||||
if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
|
||||
increment = e.getUnitsToScroll() * adj.getUnitIncrement();
|
||||
}
|
||||
else if (e.getScrollType() == MouseWheelEvent.WHEEL_BLOCK_SCROLL) {
|
||||
increment = adj.getBlockIncrement() * e.getWheelRotation();
|
||||
}
|
||||
return increment;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scroll the given Adjustable by the given amount. Checks the Adjustable's
|
||||
* bounds and sets the new value to the Adjustable.
|
||||
*/
|
||||
public static void scrollAdjustable(Adjustable adj, int amount) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
if (adj == null) {
|
||||
log.fine("Assertion (adj != null) failed");
|
||||
}
|
||||
if (amount == 0) {
|
||||
log.fine("Assertion (amount != 0) failed");
|
||||
}
|
||||
}
|
||||
|
||||
int current = adj.getValue();
|
||||
int upperLimit = adj.getMaximum() - adj.getVisibleAmount();
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer("doScrolling by " + amount);
|
||||
}
|
||||
|
||||
if (amount > 0 && current < upperLimit) { // still some room to scroll
|
||||
// down
|
||||
if (current + amount < upperLimit) {
|
||||
adj.setValue(current + amount);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
adj.setValue(upperLimit);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (amount < 0 && current > adj.getMinimum()) { // still some room
|
||||
// to scroll up
|
||||
if (current + amount > adj.getMinimum()) {
|
||||
adj.setValue(current + amount);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
adj.setValue(adj.getMinimum());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
49
jdkSrc/jdk8/sun/awt/SubRegionShowable.java
Normal file
49
jdkSrc/jdk8/sun/awt/SubRegionShowable.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2008, 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;
|
||||
|
||||
/**
|
||||
* Interface used by Swing to make copies from the Swing back buffer
|
||||
* more optimal when using BufferStrategy; no need to copy the entire
|
||||
* buffer when only a small sub-region has changed.
|
||||
* @see javax.swing.BufferStrategyPaintManager
|
||||
*
|
||||
*/
|
||||
public interface SubRegionShowable {
|
||||
/**
|
||||
* Shows the specific subregion.
|
||||
*/
|
||||
public void show(int x1, int y1, int x2, int y2);
|
||||
|
||||
/**
|
||||
* Shows the specified region if the buffer is not lost and the dimensions
|
||||
* of the back-buffer match those of the component.
|
||||
*
|
||||
* @return true if successful
|
||||
*/
|
||||
// NOTE: this is invoked by swing on the toolkit thread!
|
||||
public boolean showIfNotLost(int x1, int y1, int x2, int y2);
|
||||
}
|
||||
186
jdkSrc/jdk8/sun/awt/SunDisplayChanger.java
Normal file
186
jdkSrc/jdk8/sun/awt/SunDisplayChanger.java
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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;
|
||||
|
||||
import java.awt.IllegalComponentStateException;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
/**
|
||||
* This class is used to aid in keeping track of DisplayChangedListeners and
|
||||
* notifying them when a display change has taken place. DisplayChangedListeners
|
||||
* are notified when the display's bit depth is changed, or when a top-level
|
||||
* window has been dragged onto another screen.
|
||||
*
|
||||
* It is safe for a DisplayChangedListener to be added while the list is being
|
||||
* iterated.
|
||||
*
|
||||
* The displayChanged() call is propagated after some occurrence (either
|
||||
* due to user action or some other application) causes the display mode
|
||||
* (e.g., depth or resolution) to change. All heavyweight components need
|
||||
* to know when this happens because they need to create new surfaceData
|
||||
* objects based on the new depth.
|
||||
*
|
||||
* displayChanged() is also called on Windows when they are moved from one
|
||||
* screen to another on a system equipped with multiple displays.
|
||||
*/
|
||||
public class SunDisplayChanger {
|
||||
|
||||
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.multiscreen.SunDisplayChanger");
|
||||
|
||||
// Create a new synchronized map with initial capacity of one listener.
|
||||
// It is asserted that the most common case is to have one GraphicsDevice
|
||||
// and one top-level Window.
|
||||
private Map<DisplayChangedListener, Void> listeners =
|
||||
Collections.synchronizedMap(new WeakHashMap<DisplayChangedListener, Void>(1));
|
||||
|
||||
public SunDisplayChanger() {}
|
||||
|
||||
/*
|
||||
* Add a DisplayChangeListener to this SunDisplayChanger so that it is
|
||||
* notified when the display is changed.
|
||||
*/
|
||||
public void add(DisplayChangedListener theListener) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
if (theListener == null) {
|
||||
log.fine("Assertion (theListener != null) failed");
|
||||
}
|
||||
}
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer("Adding listener: " + theListener);
|
||||
}
|
||||
listeners.put(theListener, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the given DisplayChangeListener from this SunDisplayChanger.
|
||||
*/
|
||||
public void remove(DisplayChangedListener theListener) {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
if (theListener == null) {
|
||||
log.fine("Assertion (theListener != null) failed");
|
||||
}
|
||||
}
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
log.finer("Removing listener: " + theListener);
|
||||
}
|
||||
listeners.remove(theListener);
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify our list of DisplayChangedListeners that a display change has
|
||||
* taken place by calling their displayChanged() methods.
|
||||
*/
|
||||
public void notifyListeners() {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
log.finest("notifyListeners");
|
||||
}
|
||||
// This method is implemented by making a clone of the set of listeners,
|
||||
// and then iterating over the clone. This is because during the course
|
||||
// of responding to a display change, it may be appropriate for a
|
||||
// DisplayChangedListener to add or remove itself from a SunDisplayChanger.
|
||||
// If the set itself were iterated over, rather than a clone, it is
|
||||
// trivial to get a ConcurrentModificationException by having a
|
||||
// DisplayChangedListener remove itself from its list.
|
||||
// Because all display change handling is done on the event thread,
|
||||
// synchronization provides no protection against modifying the listener
|
||||
// list while in the middle of iterating over it. -bchristi 7/10/2001
|
||||
|
||||
Set<DisplayChangedListener> cloneSet;
|
||||
|
||||
synchronized(listeners) {
|
||||
cloneSet = new HashSet<DisplayChangedListener>(listeners.keySet());
|
||||
}
|
||||
|
||||
Iterator<DisplayChangedListener> itr = cloneSet.iterator();
|
||||
while (itr.hasNext()) {
|
||||
DisplayChangedListener current = itr.next();
|
||||
try {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
log.finest("displayChanged for listener: " + current);
|
||||
}
|
||||
current.displayChanged();
|
||||
} catch (IllegalComponentStateException e) {
|
||||
// This DisplayChangeListener is no longer valid. Most
|
||||
// likely, a top-level window was dispose()d, but its
|
||||
// Java objects have not yet been garbage collected. In any
|
||||
// case, we no longer need to track this listener, though we
|
||||
// do need to remove it from the original list, not the clone.
|
||||
listeners.remove(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify our list of DisplayChangedListeners that a palette change has
|
||||
* taken place by calling their paletteChanged() methods.
|
||||
*/
|
||||
public void notifyPaletteChanged() {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
log.finest("notifyPaletteChanged");
|
||||
}
|
||||
// This method is implemented by making a clone of the set of listeners,
|
||||
// and then iterating over the clone. This is because during the course
|
||||
// of responding to a display change, it may be appropriate for a
|
||||
// DisplayChangedListener to add or remove itself from a SunDisplayChanger.
|
||||
// If the set itself were iterated over, rather than a clone, it is
|
||||
// trivial to get a ConcurrentModificationException by having a
|
||||
// DisplayChangedListener remove itself from its list.
|
||||
// Because all display change handling is done on the event thread,
|
||||
// synchronization provides no protection against modifying the listener
|
||||
// list while in the middle of iterating over it. -bchristi 7/10/2001
|
||||
|
||||
Set<DisplayChangedListener> cloneSet;
|
||||
|
||||
synchronized (listeners) {
|
||||
cloneSet = new HashSet<DisplayChangedListener>(listeners.keySet());
|
||||
}
|
||||
Iterator<DisplayChangedListener> itr = cloneSet.iterator();
|
||||
while (itr.hasNext()) {
|
||||
DisplayChangedListener current = itr.next();
|
||||
try {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINEST)) {
|
||||
log.finest("paletteChanged for listener: " + current);
|
||||
}
|
||||
current.paletteChanged();
|
||||
} catch (IllegalComponentStateException e) {
|
||||
// This DisplayChangeListener is no longer valid. Most
|
||||
// likely, a top-level window was dispose()d, but its
|
||||
// Java objects have not yet been garbage collected. In any
|
||||
// case, we no longer need to track this listener, though we
|
||||
// do need to remove it from the original list, not the clone.
|
||||
listeners.remove(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
159
jdkSrc/jdk8/sun/awt/SunGraphicsCallback.java
Normal file
159
jdkSrc/jdk8/sun/awt/SunGraphicsCallback.java
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, 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;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
public abstract class SunGraphicsCallback {
|
||||
public static final int HEAVYWEIGHTS = 0x1;
|
||||
public static final int LIGHTWEIGHTS = 0x2;
|
||||
public static final int TWO_PASSES = 0x4;
|
||||
|
||||
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.SunGraphicsCallback");
|
||||
|
||||
public abstract void run(Component comp, Graphics cg);
|
||||
|
||||
protected void constrainGraphics(Graphics g, Rectangle bounds) {
|
||||
if (g instanceof ConstrainableGraphics) {
|
||||
((ConstrainableGraphics)g).constrain(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
} else {
|
||||
g.translate(bounds.x, bounds.y);
|
||||
}
|
||||
g.clipRect(0, 0, bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public final void runOneComponent(Component comp, Rectangle bounds,
|
||||
Graphics g, Shape clip,
|
||||
int weightFlags) {
|
||||
if (comp == null || comp.getPeer() == null || !comp.isVisible()) {
|
||||
return;
|
||||
}
|
||||
boolean lightweight = comp.isLightweight();
|
||||
if ((lightweight && (weightFlags & LIGHTWEIGHTS) == 0) ||
|
||||
(!lightweight && (weightFlags & HEAVYWEIGHTS) == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bounds == null) {
|
||||
bounds = comp.getBounds();
|
||||
}
|
||||
|
||||
if (clip == null || clip.intersects(bounds)) {
|
||||
Graphics cg = g.create();
|
||||
try {
|
||||
constrainGraphics(cg, bounds);
|
||||
cg.setFont(comp.getFont());
|
||||
cg.setColor(comp.getForeground());
|
||||
if (cg instanceof Graphics2D) {
|
||||
((Graphics2D)cg).setBackground(comp.getBackground());
|
||||
} else if (cg instanceof Graphics2Delegate) {
|
||||
((Graphics2Delegate)cg).setBackground(
|
||||
comp.getBackground());
|
||||
}
|
||||
run(comp, cg);
|
||||
} finally {
|
||||
cg.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void runComponents(Component[] comps, Graphics g,
|
||||
int weightFlags) {
|
||||
int ncomponents = comps.length;
|
||||
Shape clip = g.getClip();
|
||||
|
||||
if (log.isLoggable(PlatformLogger.Level.FINER) && (clip != null)) {
|
||||
Rectangle newrect = clip.getBounds();
|
||||
log.finer("x = " + newrect.x + ", y = " + newrect.y +
|
||||
", width = " + newrect.width +
|
||||
", height = " + newrect.height);
|
||||
}
|
||||
|
||||
// A seriously sad hack--
|
||||
// Lightweight components always paint behind peered components,
|
||||
// even if they are at the top of the Z order. We emulate this
|
||||
// behavior by making two printing passes: the first for lightweights;
|
||||
// the second for heavyweights.
|
||||
//
|
||||
// ToDo(dpm): Either build a list of heavyweights during the
|
||||
// lightweight pass, or redesign the components array to keep
|
||||
// lightweights and heavyweights separate.
|
||||
if ((weightFlags & TWO_PASSES) != 0) {
|
||||
for (int i = ncomponents - 1; i >= 0; i--) {
|
||||
runOneComponent(comps[i], null, g, clip, LIGHTWEIGHTS);
|
||||
}
|
||||
for (int i = ncomponents - 1; i >= 0; i--) {
|
||||
runOneComponent(comps[i], null, g, clip, HEAVYWEIGHTS);
|
||||
}
|
||||
} else {
|
||||
for (int i = ncomponents - 1; i >= 0; i--) {
|
||||
runOneComponent(comps[i], null, g, clip, weightFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class PaintHeavyweightComponentsCallback
|
||||
extends SunGraphicsCallback
|
||||
{
|
||||
private static PaintHeavyweightComponentsCallback instance =
|
||||
new PaintHeavyweightComponentsCallback();
|
||||
|
||||
private PaintHeavyweightComponentsCallback() {}
|
||||
public void run(Component comp, Graphics cg) {
|
||||
if (!comp.isLightweight()) {
|
||||
comp.paintAll(cg);
|
||||
} else if (comp instanceof Container) {
|
||||
runComponents(((Container)comp).getComponents(), cg,
|
||||
LIGHTWEIGHTS | HEAVYWEIGHTS);
|
||||
}
|
||||
}
|
||||
public static PaintHeavyweightComponentsCallback getInstance() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
public static final class PrintHeavyweightComponentsCallback
|
||||
extends SunGraphicsCallback
|
||||
{
|
||||
private static PrintHeavyweightComponentsCallback instance =
|
||||
new PrintHeavyweightComponentsCallback();
|
||||
|
||||
private PrintHeavyweightComponentsCallback() {}
|
||||
public void run(Component comp, Graphics cg) {
|
||||
if (!comp.isLightweight()) {
|
||||
comp.printAll(cg);
|
||||
} else if (comp instanceof Container) {
|
||||
runComponents(((Container)comp).getComponents(), cg,
|
||||
LIGHTWEIGHTS | HEAVYWEIGHTS);
|
||||
}
|
||||
}
|
||||
public static PrintHeavyweightComponentsCallback getInstance() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
506
jdkSrc/jdk8/sun/awt/SunHints.java
Normal file
506
jdkSrc/jdk8/sun/awt/SunHints.java
Normal file
@@ -0,0 +1,506 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, 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;
|
||||
|
||||
import java.awt.RenderingHints;
|
||||
import java.lang.annotation.Native;
|
||||
|
||||
/**
|
||||
* This class contains rendering hints that can be used by the
|
||||
* {@link java.awt.Graphics2D} class, and classes that implement
|
||||
* {@link java.awt.image.BufferedImageOp} and
|
||||
* {@link java.awt.image.Raster}.
|
||||
*/
|
||||
public class SunHints {
|
||||
/**
|
||||
* Defines the type of all keys used to control various
|
||||
* aspects of the rendering and imaging pipelines. Instances
|
||||
* of this class are immutable and unique which means that
|
||||
* tests for matches can be made using the == operator instead
|
||||
* of the more expensive equals() method.
|
||||
*/
|
||||
public static class Key extends RenderingHints.Key {
|
||||
String description;
|
||||
|
||||
/**
|
||||
* Construct a key using the indicated private key. Each
|
||||
* subclass of Key maintains its own unique domain of integer
|
||||
* keys. No two objects with the same integer key and of the
|
||||
* same specific subclass can be constructed. An exception
|
||||
* will be thrown if an attempt is made to construct another
|
||||
* object of a given class with the same integer key as a
|
||||
* pre-existing instance of that subclass of Key.
|
||||
*/
|
||||
public Key(int privatekey, String description) {
|
||||
super(privatekey);
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numeric index associated with this Key. This
|
||||
* is useful for use in switch statements and quick lookups
|
||||
* of the setting of a particular key.
|
||||
*/
|
||||
public final int getIndex() {
|
||||
return intKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the Key.
|
||||
*/
|
||||
public final String toString() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified object is a valid value
|
||||
* for this Key.
|
||||
*/
|
||||
public boolean isCompatibleValue(Object val) {
|
||||
if (val instanceof Value) {
|
||||
return ((Value)val).isCompatibleKey(this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the type of all "enumerative" values used to control
|
||||
* various aspects of the rendering and imaging pipelines. Instances
|
||||
* of this class are immutable and unique which means that
|
||||
* tests for matches can be made using the == operator instead
|
||||
* of the more expensive equals() method.
|
||||
*/
|
||||
public static class Value {
|
||||
private SunHints.Key myKey;
|
||||
private int index;
|
||||
private String description;
|
||||
|
||||
private static Value[][] ValueObjects =
|
||||
new Value[NUM_KEYS][VALS_PER_KEY];
|
||||
|
||||
private synchronized static void register(SunHints.Key key,
|
||||
Value value) {
|
||||
int kindex = key.getIndex();
|
||||
int vindex = value.getIndex();
|
||||
if (ValueObjects[kindex][vindex] != null) {
|
||||
throw new InternalError("duplicate index: "+vindex);
|
||||
}
|
||||
ValueObjects[kindex][vindex] = value;
|
||||
}
|
||||
|
||||
public static Value get(int keyindex, int valueindex) {
|
||||
return ValueObjects[keyindex][valueindex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a value using the indicated private index. Each
|
||||
* subclass of Value maintains its own unique domain of integer
|
||||
* indices. Enforcing the uniqueness of the integer indices
|
||||
* is left to the subclass.
|
||||
*/
|
||||
public Value(SunHints.Key key, int index, String description) {
|
||||
this.myKey = key;
|
||||
this.index = index;
|
||||
this.description = description;
|
||||
|
||||
register(key, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numeric index associated with this Key. This
|
||||
* is useful for use in switch statements and quick lookups
|
||||
* of the setting of a particular key.
|
||||
*/
|
||||
public final int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this Value.
|
||||
*/
|
||||
public final String toString() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified object is a valid Key
|
||||
* for this Value.
|
||||
*/
|
||||
public final boolean isCompatibleKey(Key k) {
|
||||
return myKey == k;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hash code for all SunHints.Value objects will be the same
|
||||
* as the system identity code of the object as defined by the
|
||||
* System.identityHashCode() method.
|
||||
*/
|
||||
public final int hashCode() {
|
||||
return System.identityHashCode(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* The equals method for all SunHints.Value objects will return
|
||||
* the same result as the equality operator '=='.
|
||||
*/
|
||||
public final boolean equals(Object o) {
|
||||
return this == o;
|
||||
}
|
||||
}
|
||||
|
||||
private static final int NUM_KEYS = 10;
|
||||
private static final int VALS_PER_KEY = 8;
|
||||
|
||||
/**
|
||||
* Rendering hint key and values
|
||||
*/
|
||||
@Native public static final int INTKEY_RENDERING = 0;
|
||||
@Native public static final int INTVAL_RENDER_DEFAULT = 0;
|
||||
@Native public static final int INTVAL_RENDER_SPEED = 1;
|
||||
@Native public static final int INTVAL_RENDER_QUALITY = 2;
|
||||
|
||||
/**
|
||||
* Antialiasing hint key and values
|
||||
*/
|
||||
@Native public static final int INTKEY_ANTIALIASING = 1;
|
||||
@Native public static final int INTVAL_ANTIALIAS_DEFAULT = 0;
|
||||
@Native public static final int INTVAL_ANTIALIAS_OFF = 1;
|
||||
@Native public static final int INTVAL_ANTIALIAS_ON = 2;
|
||||
|
||||
/**
|
||||
* Text antialiasing hint key and values
|
||||
*/
|
||||
@Native public static final int INTKEY_TEXT_ANTIALIASING = 2;
|
||||
@Native public static final int INTVAL_TEXT_ANTIALIAS_DEFAULT = 0;
|
||||
@Native public static final int INTVAL_TEXT_ANTIALIAS_OFF = 1;
|
||||
@Native public static final int INTVAL_TEXT_ANTIALIAS_ON = 2;
|
||||
@Native public static final int INTVAL_TEXT_ANTIALIAS_GASP = 3;
|
||||
@Native public static final int INTVAL_TEXT_ANTIALIAS_LCD_HRGB = 4;
|
||||
@Native public static final int INTVAL_TEXT_ANTIALIAS_LCD_HBGR = 5;
|
||||
@Native public static final int INTVAL_TEXT_ANTIALIAS_LCD_VRGB = 6;
|
||||
@Native public static final int INTVAL_TEXT_ANTIALIAS_LCD_VBGR = 7;
|
||||
|
||||
/**
|
||||
* Font fractional metrics hint key and values
|
||||
*/
|
||||
@Native public static final int INTKEY_FRACTIONALMETRICS = 3;
|
||||
@Native public static final int INTVAL_FRACTIONALMETRICS_DEFAULT = 0;
|
||||
@Native public static final int INTVAL_FRACTIONALMETRICS_OFF = 1;
|
||||
@Native public static final int INTVAL_FRACTIONALMETRICS_ON = 2;
|
||||
|
||||
/**
|
||||
* Dithering hint key and values
|
||||
*/
|
||||
@Native public static final int INTKEY_DITHERING = 4;
|
||||
@Native public static final int INTVAL_DITHER_DEFAULT = 0;
|
||||
@Native public static final int INTVAL_DITHER_DISABLE = 1;
|
||||
@Native public static final int INTVAL_DITHER_ENABLE = 2;
|
||||
|
||||
/**
|
||||
* Interpolation hint key and values
|
||||
*/
|
||||
@Native public static final int INTKEY_INTERPOLATION = 5;
|
||||
@Native public static final int INTVAL_INTERPOLATION_NEAREST_NEIGHBOR = 0;
|
||||
@Native public static final int INTVAL_INTERPOLATION_BILINEAR = 1;
|
||||
@Native public static final int INTVAL_INTERPOLATION_BICUBIC = 2;
|
||||
|
||||
/**
|
||||
* Alpha interpolation hint key and values
|
||||
*/
|
||||
@Native public static final int INTKEY_ALPHA_INTERPOLATION = 6;
|
||||
@Native public static final int INTVAL_ALPHA_INTERPOLATION_DEFAULT = 0;
|
||||
@Native public static final int INTVAL_ALPHA_INTERPOLATION_SPEED = 1;
|
||||
@Native public static final int INTVAL_ALPHA_INTERPOLATION_QUALITY = 2;
|
||||
|
||||
/**
|
||||
* Color rendering hint key and values
|
||||
*/
|
||||
@Native public static final int INTKEY_COLOR_RENDERING = 7;
|
||||
@Native public static final int INTVAL_COLOR_RENDER_DEFAULT = 0;
|
||||
@Native public static final int INTVAL_COLOR_RENDER_SPEED = 1;
|
||||
@Native public static final int INTVAL_COLOR_RENDER_QUALITY = 2;
|
||||
|
||||
/**
|
||||
* Stroke normalization control hint key and values
|
||||
*/
|
||||
@Native public static final int INTKEY_STROKE_CONTROL = 8;
|
||||
@Native public static final int INTVAL_STROKE_DEFAULT = 0;
|
||||
@Native public static final int INTVAL_STROKE_NORMALIZE = 1;
|
||||
@Native public static final int INTVAL_STROKE_PURE = 2;
|
||||
|
||||
/**
|
||||
* Image scaling hint key and values
|
||||
*/
|
||||
@Native public static final int INTKEY_RESOLUTION_VARIANT = 9;
|
||||
@Native public static final int INTVAL_RESOLUTION_VARIANT_DEFAULT = 0;
|
||||
@Native public static final int INTVAL_RESOLUTION_VARIANT_OFF = 1;
|
||||
@Native public static final int INTVAL_RESOLUTION_VARIANT_ON = 2;
|
||||
/**
|
||||
* LCD text contrast control hint key.
|
||||
* Value is "100" to make discontiguous with the others which
|
||||
* are all enumerative and are of a different class.
|
||||
*/
|
||||
@Native public static final int INTKEY_AATEXT_LCD_CONTRAST = 100;
|
||||
|
||||
/**
|
||||
* Rendering hint key and value objects
|
||||
*/
|
||||
public static final Key KEY_RENDERING =
|
||||
new SunHints.Key(SunHints.INTKEY_RENDERING,
|
||||
"Global rendering quality key");
|
||||
public static final Object VALUE_RENDER_SPEED =
|
||||
new SunHints.Value(KEY_RENDERING,
|
||||
SunHints.INTVAL_RENDER_SPEED,
|
||||
"Fastest rendering methods");
|
||||
public static final Object VALUE_RENDER_QUALITY =
|
||||
new SunHints.Value(KEY_RENDERING,
|
||||
SunHints.INTVAL_RENDER_QUALITY,
|
||||
"Highest quality rendering methods");
|
||||
public static final Object VALUE_RENDER_DEFAULT =
|
||||
new SunHints.Value(KEY_RENDERING,
|
||||
SunHints.INTVAL_RENDER_DEFAULT,
|
||||
"Default rendering methods");
|
||||
|
||||
/**
|
||||
* Antialiasing hint key and value objects
|
||||
*/
|
||||
public static final Key KEY_ANTIALIASING =
|
||||
new SunHints.Key(SunHints.INTKEY_ANTIALIASING,
|
||||
"Global antialiasing enable key");
|
||||
public static final Object VALUE_ANTIALIAS_ON =
|
||||
new SunHints.Value(KEY_ANTIALIASING,
|
||||
SunHints.INTVAL_ANTIALIAS_ON,
|
||||
"Antialiased rendering mode");
|
||||
public static final Object VALUE_ANTIALIAS_OFF =
|
||||
new SunHints.Value(KEY_ANTIALIASING,
|
||||
SunHints.INTVAL_ANTIALIAS_OFF,
|
||||
"Nonantialiased rendering mode");
|
||||
public static final Object VALUE_ANTIALIAS_DEFAULT =
|
||||
new SunHints.Value(KEY_ANTIALIASING,
|
||||
SunHints.INTVAL_ANTIALIAS_DEFAULT,
|
||||
"Default antialiasing rendering mode");
|
||||
|
||||
/**
|
||||
* Text antialiasing hint key and value objects
|
||||
*/
|
||||
public static final Key KEY_TEXT_ANTIALIASING =
|
||||
new SunHints.Key(SunHints.INTKEY_TEXT_ANTIALIASING,
|
||||
"Text-specific antialiasing enable key");
|
||||
public static final Object VALUE_TEXT_ANTIALIAS_ON =
|
||||
new SunHints.Value(KEY_TEXT_ANTIALIASING,
|
||||
SunHints.INTVAL_TEXT_ANTIALIAS_ON,
|
||||
"Antialiased text mode");
|
||||
public static final Object VALUE_TEXT_ANTIALIAS_OFF =
|
||||
new SunHints.Value(KEY_TEXT_ANTIALIASING,
|
||||
SunHints.INTVAL_TEXT_ANTIALIAS_OFF,
|
||||
"Nonantialiased text mode");
|
||||
public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT =
|
||||
new SunHints.Value(KEY_TEXT_ANTIALIASING,
|
||||
SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT,
|
||||
"Default antialiasing text mode");
|
||||
public static final Object VALUE_TEXT_ANTIALIAS_GASP =
|
||||
new SunHints.Value(KEY_TEXT_ANTIALIASING,
|
||||
SunHints.INTVAL_TEXT_ANTIALIAS_GASP,
|
||||
"gasp antialiasing text mode");
|
||||
public static final Object VALUE_TEXT_ANTIALIAS_LCD_HRGB =
|
||||
new SunHints.Value(KEY_TEXT_ANTIALIASING,
|
||||
SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB,
|
||||
"LCD HRGB antialiasing text mode");
|
||||
public static final Object VALUE_TEXT_ANTIALIAS_LCD_HBGR =
|
||||
new SunHints.Value(KEY_TEXT_ANTIALIASING,
|
||||
SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HBGR,
|
||||
"LCD HBGR antialiasing text mode");
|
||||
public static final Object VALUE_TEXT_ANTIALIAS_LCD_VRGB =
|
||||
new SunHints.Value(KEY_TEXT_ANTIALIASING,
|
||||
SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB,
|
||||
"LCD VRGB antialiasing text mode");
|
||||
public static final Object VALUE_TEXT_ANTIALIAS_LCD_VBGR =
|
||||
new SunHints.Value(KEY_TEXT_ANTIALIASING,
|
||||
SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VBGR,
|
||||
"LCD VBGR antialiasing text mode");
|
||||
|
||||
/**
|
||||
* Font fractional metrics hint key and value objects
|
||||
*/
|
||||
public static final Key KEY_FRACTIONALMETRICS =
|
||||
new SunHints.Key(SunHints.INTKEY_FRACTIONALMETRICS,
|
||||
"Fractional metrics enable key");
|
||||
public static final Object VALUE_FRACTIONALMETRICS_ON =
|
||||
new SunHints.Value(KEY_FRACTIONALMETRICS,
|
||||
SunHints.INTVAL_FRACTIONALMETRICS_ON,
|
||||
"Fractional text metrics mode");
|
||||
public static final Object VALUE_FRACTIONALMETRICS_OFF =
|
||||
new SunHints.Value(KEY_FRACTIONALMETRICS,
|
||||
SunHints.INTVAL_FRACTIONALMETRICS_OFF,
|
||||
"Integer text metrics mode");
|
||||
public static final Object VALUE_FRACTIONALMETRICS_DEFAULT =
|
||||
new SunHints.Value(KEY_FRACTIONALMETRICS,
|
||||
SunHints.INTVAL_FRACTIONALMETRICS_DEFAULT,
|
||||
"Default fractional text metrics mode");
|
||||
|
||||
/**
|
||||
* Dithering hint key and value objects
|
||||
*/
|
||||
public static final Key KEY_DITHERING =
|
||||
new SunHints.Key(SunHints.INTKEY_DITHERING,
|
||||
"Dithering quality key");
|
||||
public static final Object VALUE_DITHER_ENABLE =
|
||||
new SunHints.Value(KEY_DITHERING,
|
||||
SunHints.INTVAL_DITHER_ENABLE,
|
||||
"Dithered rendering mode");
|
||||
public static final Object VALUE_DITHER_DISABLE =
|
||||
new SunHints.Value(KEY_DITHERING,
|
||||
SunHints.INTVAL_DITHER_DISABLE,
|
||||
"Nondithered rendering mode");
|
||||
public static final Object VALUE_DITHER_DEFAULT =
|
||||
new SunHints.Value(KEY_DITHERING,
|
||||
SunHints.INTVAL_DITHER_DEFAULT,
|
||||
"Default dithering mode");
|
||||
|
||||
/**
|
||||
* Interpolation hint key and value objects
|
||||
*/
|
||||
public static final Key KEY_INTERPOLATION =
|
||||
new SunHints.Key(SunHints.INTKEY_INTERPOLATION,
|
||||
"Image interpolation method key");
|
||||
public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR =
|
||||
new SunHints.Value(KEY_INTERPOLATION,
|
||||
SunHints.INTVAL_INTERPOLATION_NEAREST_NEIGHBOR,
|
||||
"Nearest Neighbor image interpolation mode");
|
||||
public static final Object VALUE_INTERPOLATION_BILINEAR =
|
||||
new SunHints.Value(KEY_INTERPOLATION,
|
||||
SunHints.INTVAL_INTERPOLATION_BILINEAR,
|
||||
"Bilinear image interpolation mode");
|
||||
public static final Object VALUE_INTERPOLATION_BICUBIC =
|
||||
new SunHints.Value(KEY_INTERPOLATION,
|
||||
SunHints.INTVAL_INTERPOLATION_BICUBIC,
|
||||
"Bicubic image interpolation mode");
|
||||
|
||||
/**
|
||||
* Alpha interpolation hint key and value objects
|
||||
*/
|
||||
public static final Key KEY_ALPHA_INTERPOLATION =
|
||||
new SunHints.Key(SunHints.INTKEY_ALPHA_INTERPOLATION,
|
||||
"Alpha blending interpolation method key");
|
||||
public static final Object VALUE_ALPHA_INTERPOLATION_SPEED =
|
||||
new SunHints.Value(KEY_ALPHA_INTERPOLATION,
|
||||
SunHints.INTVAL_ALPHA_INTERPOLATION_SPEED,
|
||||
"Fastest alpha blending methods");
|
||||
public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY =
|
||||
new SunHints.Value(KEY_ALPHA_INTERPOLATION,
|
||||
SunHints.INTVAL_ALPHA_INTERPOLATION_QUALITY,
|
||||
"Highest quality alpha blending methods");
|
||||
public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT =
|
||||
new SunHints.Value(KEY_ALPHA_INTERPOLATION,
|
||||
SunHints.INTVAL_ALPHA_INTERPOLATION_DEFAULT,
|
||||
"Default alpha blending methods");
|
||||
|
||||
/**
|
||||
* Color rendering hint key and value objects
|
||||
*/
|
||||
public static final Key KEY_COLOR_RENDERING =
|
||||
new SunHints.Key(SunHints.INTKEY_COLOR_RENDERING,
|
||||
"Color rendering quality key");
|
||||
public static final Object VALUE_COLOR_RENDER_SPEED =
|
||||
new SunHints.Value(KEY_COLOR_RENDERING,
|
||||
SunHints.INTVAL_COLOR_RENDER_SPEED,
|
||||
"Fastest color rendering mode");
|
||||
public static final Object VALUE_COLOR_RENDER_QUALITY =
|
||||
new SunHints.Value(KEY_COLOR_RENDERING,
|
||||
SunHints.INTVAL_COLOR_RENDER_QUALITY,
|
||||
"Highest quality color rendering mode");
|
||||
public static final Object VALUE_COLOR_RENDER_DEFAULT =
|
||||
new SunHints.Value(KEY_COLOR_RENDERING,
|
||||
SunHints.INTVAL_COLOR_RENDER_DEFAULT,
|
||||
"Default color rendering mode");
|
||||
|
||||
/**
|
||||
* Stroke normalization control hint key and value objects
|
||||
*/
|
||||
public static final Key KEY_STROKE_CONTROL =
|
||||
new SunHints.Key(SunHints.INTKEY_STROKE_CONTROL,
|
||||
"Stroke normalization control key");
|
||||
public static final Object VALUE_STROKE_DEFAULT =
|
||||
new SunHints.Value(KEY_STROKE_CONTROL,
|
||||
SunHints.INTVAL_STROKE_DEFAULT,
|
||||
"Default stroke normalization");
|
||||
public static final Object VALUE_STROKE_NORMALIZE =
|
||||
new SunHints.Value(KEY_STROKE_CONTROL,
|
||||
SunHints.INTVAL_STROKE_NORMALIZE,
|
||||
"Normalize strokes for consistent rendering");
|
||||
public static final Object VALUE_STROKE_PURE =
|
||||
new SunHints.Value(KEY_STROKE_CONTROL,
|
||||
SunHints.INTVAL_STROKE_PURE,
|
||||
"Pure stroke conversion for accurate paths");
|
||||
|
||||
/**
|
||||
* Image resolution variant hint key and value objects
|
||||
*/
|
||||
public static final Key KEY_RESOLUTION_VARIANT =
|
||||
new SunHints.Key(SunHints.INTKEY_RESOLUTION_VARIANT,
|
||||
"Global image resolution variant key");
|
||||
public static final Object VALUE_RESOLUTION_VARIANT_DEFAULT =
|
||||
new SunHints.Value(KEY_RESOLUTION_VARIANT,
|
||||
SunHints.INTVAL_RESOLUTION_VARIANT_DEFAULT,
|
||||
"Choose image resolutions based on a default heuristic");
|
||||
public static final Object VALUE_RESOLUTION_VARIANT_OFF =
|
||||
new SunHints.Value(KEY_RESOLUTION_VARIANT,
|
||||
SunHints.INTVAL_RESOLUTION_VARIANT_OFF,
|
||||
"Use only the standard resolution of an image");
|
||||
public static final Object VALUE_RESOLUTION_VARIANT_ON =
|
||||
new SunHints.Value(KEY_RESOLUTION_VARIANT,
|
||||
SunHints.INTVAL_RESOLUTION_VARIANT_ON,
|
||||
"Always use resolution-specific variants of images");
|
||||
|
||||
public static class LCDContrastKey extends Key {
|
||||
|
||||
public LCDContrastKey(int privatekey, String description) {
|
||||
super(privatekey, description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified object is a valid value
|
||||
* for this Key. The allowable range is 100 to 250.
|
||||
*/
|
||||
public final boolean isCompatibleValue(Object val) {
|
||||
if (val instanceof Integer) {
|
||||
int ival = ((Integer)val).intValue();
|
||||
return ival >= 100 && ival <= 250;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* LCD text contrast hint key
|
||||
*/
|
||||
public static final RenderingHints.Key
|
||||
KEY_TEXT_ANTIALIAS_LCD_CONTRAST =
|
||||
new LCDContrastKey(SunHints.INTKEY_AATEXT_LCD_CONTRAST,
|
||||
"Text-specific LCD contrast key");
|
||||
}
|
||||
2208
jdkSrc/jdk8/sun/awt/SunToolkit.java
Normal file
2208
jdkSrc/jdk8/sun/awt/SunToolkit.java
Normal file
File diff suppressed because it is too large
Load Diff
191
jdkSrc/jdk8/sun/awt/Symbol.java
Normal file
191
jdkSrc/jdk8/sun/awt/Symbol.java
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, 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;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.*;
|
||||
|
||||
public class Symbol extends Charset {
|
||||
public Symbol () {
|
||||
super("Symbol", null);
|
||||
}
|
||||
public CharsetEncoder newEncoder() {
|
||||
return new Encoder(this);
|
||||
}
|
||||
|
||||
/* Seems like supporting a decoder is required, but we aren't going
|
||||
* to be publically exposing this class, so no need to waste work
|
||||
*/
|
||||
public CharsetDecoder newDecoder() {
|
||||
throw new Error("Decoder is not implemented for Symbol Charset");
|
||||
}
|
||||
|
||||
public boolean contains(Charset cs) {
|
||||
return cs instanceof Symbol;
|
||||
}
|
||||
|
||||
private static class Encoder extends CharsetEncoder {
|
||||
public Encoder(Charset cs) {
|
||||
super(cs, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
public boolean canEncode(char c) {
|
||||
if (c >= 0x2200 && c <= 0x22ef) {
|
||||
if (table_math[c - 0x2200] != 0x00) {
|
||||
return true;
|
||||
}
|
||||
} else if (c >= 0x0391 && c <= 0x03d6) {
|
||||
if (table_greek[c - 0x0391] != 0x00) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
|
||||
char[] sa = src.array();
|
||||
int sp = src.arrayOffset() + src.position();
|
||||
int sl = src.arrayOffset() + src.limit();
|
||||
assert (sp <= sl);
|
||||
sp = (sp <= sl ? sp : sl);
|
||||
byte[] da = dst.array();
|
||||
int dp = dst.arrayOffset() + dst.position();
|
||||
int dl = dst.arrayOffset() + dst.limit();
|
||||
assert (dp <= dl);
|
||||
dp = (dp <= dl ? dp : dl);
|
||||
|
||||
try {
|
||||
while (sp < sl) {
|
||||
char c = sa[sp];
|
||||
if (dl - dp < 1)
|
||||
return CoderResult.OVERFLOW;
|
||||
if (!canEncode(c))
|
||||
return CoderResult.unmappableForLength(1);
|
||||
sp++;
|
||||
if (c >= 0x2200 && c <= 0x22ef){
|
||||
da[dp++] = table_math[c - 0x2200];
|
||||
} else if (c >= 0x0391 && c <= 0x03d6) {
|
||||
da[dp++]= table_greek[c - 0x0391];
|
||||
}
|
||||
}
|
||||
return CoderResult.UNDERFLOW;
|
||||
} finally {
|
||||
src.position(sp - src.arrayOffset());
|
||||
dst.position(dp - dst.arrayOffset());
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] table_math = {
|
||||
(byte)0042, (byte)0000, (byte)0144, (byte)0044,
|
||||
(byte)0000, (byte)0306, (byte)0104, (byte)0321, // 00
|
||||
(byte)0316, (byte)0317, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0047, (byte)0000, (byte)0120,
|
||||
(byte)0000, (byte)0345, (byte)0055, (byte)0000,
|
||||
(byte)0000, (byte)0244, (byte)0000, (byte)0052, // 10
|
||||
(byte)0260, (byte)0267, (byte)0326, (byte)0000,
|
||||
(byte)0000, (byte)0265, (byte)0245, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0275,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0331, // 20
|
||||
(byte)0332, (byte)0307, (byte)0310, (byte)0362,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0134, (byte)0000, (byte)0000, (byte)0000, // 30
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0176, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0100, (byte)0000, (byte)0000, // 40
|
||||
(byte)0273, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000, // 50
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0271, (byte)0272, (byte)0000, (byte)0000,
|
||||
(byte)0243, (byte)0263, (byte)0000, (byte)0000, // 60
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000, // 70
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0314, (byte)0311,
|
||||
(byte)0313, (byte)0000, (byte)0315, (byte)0312, // 80
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0305, (byte)0000, (byte)0304, // 90
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0136, (byte)0000, (byte)0000, // a0
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000, // b0
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0340, (byte)0327, (byte)0000, (byte)0000, // c0
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000, // d0
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000, // e0
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0274,
|
||||
};
|
||||
|
||||
private static byte[] table_greek = {
|
||||
(byte)0101, (byte)0102, (byte)0107,
|
||||
(byte)0104, (byte)0105, (byte)0132, (byte)0110, // 90
|
||||
(byte)0121, (byte)0111, (byte)0113, (byte)0114,
|
||||
(byte)0115, (byte)0116, (byte)0130, (byte)0117,
|
||||
(byte)0120, (byte)0122, (byte)0000, (byte)0123,
|
||||
(byte)0124, (byte)0125, (byte)0106, (byte)0103, // a0
|
||||
(byte)0131, (byte)0127, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0141, (byte)0142, (byte)0147,
|
||||
(byte)0144, (byte)0145, (byte)0172, (byte)0150, // b0
|
||||
(byte)0161, (byte)0151, (byte)0153, (byte)0154,
|
||||
(byte)0155, (byte)0156, (byte)0170, (byte)0157,
|
||||
(byte)0160, (byte)0162, (byte)0126, (byte)0163,
|
||||
(byte)0164, (byte)0165, (byte)0146, (byte)0143, // c0
|
||||
(byte)0171, (byte)0167, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0000, (byte)0000, (byte)0000,
|
||||
(byte)0000, (byte)0112, (byte)0241, (byte)0000,
|
||||
(byte)0000, (byte)0152, (byte)0166, // d0
|
||||
};
|
||||
|
||||
/* The default implementation creates a decoder and we don't have one */
|
||||
public boolean isLegalReplacement(byte[] repl) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
jdkSrc/jdk8/sun/awt/TimedWindowEvent.java
Normal file
51
jdkSrc/jdk8/sun/awt/TimedWindowEvent.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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;
|
||||
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.Window;
|
||||
|
||||
public class TimedWindowEvent extends WindowEvent {
|
||||
|
||||
private long time;
|
||||
|
||||
public long getWhen() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public TimedWindowEvent(Window source, int id, Window opposite, long time) {
|
||||
super(source, id, opposite);
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public TimedWindowEvent(Window source, int id, Window opposite,
|
||||
int oldState, int newState, long time)
|
||||
{
|
||||
super(source, id, opposite, oldState, newState);
|
||||
this.time = time;
|
||||
}
|
||||
}
|
||||
|
||||
91
jdkSrc/jdk8/sun/awt/TracedEventQueue.java
Normal file
91
jdkSrc/jdk8/sun/awt/TracedEventQueue.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An EventQueue subclass which adds selective tracing of events as they
|
||||
* are posted to an EventQueue. Tracing is globally enabled and disabled
|
||||
* by the AWT.TraceEventPosting property in awt.properties. <P>
|
||||
*
|
||||
* The optional AWT.NoTraceIDs property defines a list of AWTEvent IDs
|
||||
* which should not be traced, such as MouseEvent.MOUSE_MOVED or PaintEvents.
|
||||
* This list is declared by specifying the decimal value of each event's ID,
|
||||
* separated by commas.
|
||||
*
|
||||
* @author Thomas Ball
|
||||
*/
|
||||
|
||||
package sun.awt;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.AWTEvent;
|
||||
import java.awt.Toolkit;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class TracedEventQueue extends EventQueue {
|
||||
|
||||
// Determines whether any event tracing is enabled.
|
||||
static boolean trace = false;
|
||||
|
||||
// The list of event IDs to ignore when tracing.
|
||||
static int suppressedIDs[] = null;
|
||||
|
||||
static {
|
||||
String s = Toolkit.getProperty("AWT.IgnoreEventIDs", "");
|
||||
if (s.length() > 0) {
|
||||
StringTokenizer st = new StringTokenizer(s, ",");
|
||||
int nIDs = st.countTokens();
|
||||
suppressedIDs = new int[nIDs];
|
||||
for (int i = 0; i < nIDs; i++) {
|
||||
String idString = st.nextToken();
|
||||
try {
|
||||
suppressedIDs[i] = Integer.parseInt(idString);
|
||||
} catch (NumberFormatException e) {
|
||||
System.err.println("Bad ID listed in AWT.IgnoreEventIDs " +
|
||||
"in awt.properties: \"" +
|
||||
idString + "\" -- skipped");
|
||||
suppressedIDs[i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
suppressedIDs = new int[0];
|
||||
}
|
||||
}
|
||||
|
||||
public void postEvent(AWTEvent theEvent) {
|
||||
boolean printEvent = true;
|
||||
int id = theEvent.getID();
|
||||
for (int i = 0; i < suppressedIDs.length; i++) {
|
||||
if (id == suppressedIDs[i]) {
|
||||
printEvent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (printEvent) {
|
||||
System.out.println(Thread.currentThread().getName() +
|
||||
": " + theEvent);
|
||||
}
|
||||
super.postEvent(theEvent);
|
||||
}
|
||||
}
|
||||
54
jdkSrc/jdk8/sun/awt/UngrabEvent.java
Normal file
54
jdkSrc/jdk8/sun/awt/UngrabEvent.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, 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;
|
||||
|
||||
import java.awt.AWTEvent;
|
||||
import java.awt.Component;
|
||||
|
||||
/**
|
||||
* Sent when one of the following events occur on the grabbed window: <ul>
|
||||
* <li> it looses focus, but not to one of the owned windows
|
||||
* <li> mouse click on the outside area happens (except for one of the owned windows)
|
||||
* <li> switch to another application or desktop happens
|
||||
* <li> click in the non-client area of the owning window or this window happens
|
||||
* </ul>
|
||||
*
|
||||
* <p>Notice that this event is not generated on mouse click inside of the window area.
|
||||
* <p>To listen for this event, install AWTEventListener with {@value sun.awt.SunToolkit#GRAB_EVENT_MASK}
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class UngrabEvent extends AWTEvent {
|
||||
|
||||
private final static int UNGRAB_EVENT_ID = 1998;
|
||||
|
||||
public UngrabEvent(Component source) {
|
||||
super(source, UNGRAB_EVENT_ID);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "sun.awt.UngrabEvent[" + getSource() + "]";
|
||||
}
|
||||
}
|
||||
73
jdkSrc/jdk8/sun/awt/Win32ColorModel24.java
Normal file
73
jdkSrc/jdk8/sun/awt/Win32ColorModel24.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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;
|
||||
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.PixelInterleavedSampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.Transparency;
|
||||
|
||||
/**
|
||||
* This class creates a standard ComponentColorModel with the slight
|
||||
* difference that it creates its Raster objects with the components
|
||||
* in the reverse order from the base ComponentColorModel to match
|
||||
* the ordering on a Windows 24-bit display.
|
||||
*/
|
||||
public class Win32ColorModel24 extends ComponentColorModel {
|
||||
public Win32ColorModel24() {
|
||||
super(ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
new int[] {8, 8, 8}, false, false,
|
||||
Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a WritableRaster with the specified width and height, that
|
||||
* has a data layout (SampleModel) compatible with this ColorModel.
|
||||
* @see WritableRaster
|
||||
* @see SampleModel
|
||||
*/
|
||||
public WritableRaster createCompatibleWritableRaster (int w, int h) {
|
||||
int[] bOffs = {2, 1, 0};
|
||||
return Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
|
||||
w, h, w*3, 3,
|
||||
bOffs, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SampleModel with the specified width and height, that
|
||||
* has a data layout compatible with this ColorModel.
|
||||
* @see SampleModel
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
int[] bOffs = {2, 1, 0};
|
||||
return new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE,
|
||||
w, h, 3, w*3, bOffs);
|
||||
}
|
||||
}
|
||||
363
jdkSrc/jdk8/sun/awt/Win32FontManager.java
Normal file
363
jdkSrc/jdk8/sun/awt/Win32FontManager.java
Normal file
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 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;
|
||||
|
||||
import java.awt.FontFormatException;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.io.File;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import sun.awt.windows.WFontConfiguration;
|
||||
import sun.font.FontManager;
|
||||
import sun.font.SunFontManager;
|
||||
import sun.font.TrueTypeFont;
|
||||
import sun.java2d.HeadlessGraphicsEnvironment;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
|
||||
/**
|
||||
* The X11 implementation of {@link FontManager}.
|
||||
*/
|
||||
public final class Win32FontManager extends SunFontManager {
|
||||
|
||||
private static TrueTypeFont eudcFont;
|
||||
|
||||
static {
|
||||
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
|
||||
public Object run() {
|
||||
String eudcFile = getEUDCFontFile();
|
||||
if (eudcFile != null) {
|
||||
try {
|
||||
/* Must use Java rasteriser since GDI doesn't
|
||||
* enumerate (allow direct use) of EUDC fonts.
|
||||
*/
|
||||
eudcFont = new TrueTypeFont(eudcFile, null, 0,
|
||||
true, false);
|
||||
} catch (FontFormatException e) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/* Used on Windows to obtain from the windows registry the name
|
||||
* of a file containing the system EUFC font. If running in one of
|
||||
* the locales for which this applies, and one is defined, the font
|
||||
* defined by this file is appended to all composite fonts as a
|
||||
* fallback component.
|
||||
*/
|
||||
private static native String getEUDCFontFile();
|
||||
|
||||
public TrueTypeFont getEUDCFont() {
|
||||
return eudcFont;
|
||||
}
|
||||
|
||||
public Win32FontManager() {
|
||||
super();
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
|
||||
/* Register the JRE fonts so that the native platform can
|
||||
* access them. This is used only on Windows so that when
|
||||
* printing the printer driver can access the fonts.
|
||||
*/
|
||||
registerJREFontsWithPlatform(jreFontDirName);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether registerFontFile expects absolute or relative
|
||||
* font file names.
|
||||
*/
|
||||
protected boolean useAbsoluteFontFileNames() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Unlike the shared code version, this expects a base file name -
|
||||
* not a full path name.
|
||||
* The font configuration file has base file names and the FontConfiguration
|
||||
* class reports these back to the GraphicsEnvironment, so these
|
||||
* are the componentFileNames of CompositeFonts.
|
||||
*/
|
||||
protected void registerFontFile(String fontFileName, String[] nativeNames,
|
||||
int fontRank, boolean defer) {
|
||||
|
||||
// REMIND: case compare depends on platform
|
||||
if (registeredFontFiles.contains(fontFileName)) {
|
||||
return;
|
||||
}
|
||||
registeredFontFiles.add(fontFileName);
|
||||
|
||||
int fontFormat;
|
||||
if (getTrueTypeFilter().accept(null, fontFileName)) {
|
||||
fontFormat = SunFontManager.FONTFORMAT_TRUETYPE;
|
||||
} else if (getType1Filter().accept(null, fontFileName)) {
|
||||
fontFormat = SunFontManager.FONTFORMAT_TYPE1;
|
||||
} else {
|
||||
/* on windows we don't use/register native fonts */
|
||||
return;
|
||||
}
|
||||
|
||||
if (fontPath == null) {
|
||||
fontPath = getPlatformFontPath(noType1Font);
|
||||
}
|
||||
|
||||
/* Look in the JRE font directory first.
|
||||
* This is playing it safe as we would want to find fonts in the
|
||||
* JRE font directory ahead of those in the system directory
|
||||
*/
|
||||
String tmpFontPath = jreFontDirName+File.pathSeparator+fontPath;
|
||||
StringTokenizer parser = new StringTokenizer(tmpFontPath,
|
||||
File.pathSeparator);
|
||||
|
||||
boolean found = false;
|
||||
try {
|
||||
while (!found && parser.hasMoreTokens()) {
|
||||
String newPath = parser.nextToken();
|
||||
boolean isJREFont = newPath.equals(jreFontDirName);
|
||||
File theFile = new File(newPath, fontFileName);
|
||||
if (theFile.canRead()) {
|
||||
found = true;
|
||||
String path = theFile.getAbsolutePath();
|
||||
if (defer) {
|
||||
registerDeferredFont(fontFileName, path,
|
||||
nativeNames,
|
||||
fontFormat, isJREFont,
|
||||
fontRank);
|
||||
} else {
|
||||
registerFontFile(path, nativeNames,
|
||||
fontFormat, isJREFont,
|
||||
fontRank);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (NoSuchElementException e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
if (!found) {
|
||||
addToMissingFontFileList(fontFileName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FontConfiguration createFontConfiguration() {
|
||||
|
||||
FontConfiguration fc = new WFontConfiguration(this);
|
||||
fc.init();
|
||||
return fc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontConfiguration createFontConfiguration(boolean preferLocaleFonts,
|
||||
boolean preferPropFonts) {
|
||||
|
||||
return new WFontConfiguration(this,
|
||||
preferLocaleFonts,preferPropFonts);
|
||||
}
|
||||
|
||||
protected void
|
||||
populateFontFileNameMap(HashMap<String,String> fontToFileMap,
|
||||
HashMap<String,String> fontToFamilyNameMap,
|
||||
HashMap<String,ArrayList<String>>
|
||||
familyToFontListMap,
|
||||
Locale locale) {
|
||||
|
||||
populateFontFileNameMap0(fontToFileMap, fontToFamilyNameMap,
|
||||
familyToFontListMap, locale);
|
||||
|
||||
}
|
||||
|
||||
private static native void
|
||||
populateFontFileNameMap0(HashMap<String,String> fontToFileMap,
|
||||
HashMap<String,String> fontToFamilyNameMap,
|
||||
HashMap<String,ArrayList<String>>
|
||||
familyToFontListMap,
|
||||
Locale locale);
|
||||
|
||||
protected synchronized native String getFontPath(boolean noType1Fonts);
|
||||
|
||||
@Override
|
||||
protected String[] getDefaultPlatformFont() {
|
||||
String[] info = new String[2];
|
||||
info[0] = "Arial";
|
||||
info[1] = "c:\\windows\\fonts";
|
||||
final String[] dirs = getPlatformFontDirs(true);
|
||||
if (dirs.length > 1) {
|
||||
String dir = (String)
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
for (int i=0; i<dirs.length; i++) {
|
||||
String path =
|
||||
dirs[i] + File.separator + "arial.ttf";
|
||||
File file = new File(path);
|
||||
if (file.exists()) {
|
||||
return dirs[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (dir != null) {
|
||||
info[1] = dir;
|
||||
}
|
||||
} else {
|
||||
info[1] = dirs[0];
|
||||
}
|
||||
info[1] = info[1] + File.separator + "arial.ttf";
|
||||
return info;
|
||||
}
|
||||
|
||||
/* register only TrueType/OpenType fonts
|
||||
* Because these need to be registed just for use when printing,
|
||||
* we defer the actual registration and the static initialiser
|
||||
* for the printing class makes the call to registerJREFontsForPrinting()
|
||||
*/
|
||||
static String fontsForPrinting = null;
|
||||
protected void registerJREFontsWithPlatform(String pathName) {
|
||||
fontsForPrinting = pathName;
|
||||
}
|
||||
|
||||
public static void registerJREFontsForPrinting() {
|
||||
final String pathName;
|
||||
synchronized (Win32GraphicsEnvironment.class) {
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
if (fontsForPrinting == null) {
|
||||
return;
|
||||
}
|
||||
pathName = fontsForPrinting;
|
||||
fontsForPrinting = null;
|
||||
}
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
File f1 = new File(pathName);
|
||||
String[] ls = f1.list(SunFontManager.getInstance().
|
||||
getTrueTypeFilter());
|
||||
if (ls == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i=0; i <ls.length; i++ ) {
|
||||
File fontFile = new File(f1, ls[i]);
|
||||
registerFontWithPlatform(fontFile.getAbsolutePath());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected static native void registerFontWithPlatform(String fontName);
|
||||
|
||||
protected static native void deRegisterFontWithPlatform(String fontName);
|
||||
|
||||
/**
|
||||
* populate the map with the most common windows fonts.
|
||||
*/
|
||||
@Override
|
||||
public HashMap<String, FamilyDescription> populateHardcodedFileNameMap() {
|
||||
HashMap<String, FamilyDescription> platformFontMap
|
||||
= new HashMap<String, FamilyDescription>();
|
||||
FamilyDescription fd;
|
||||
|
||||
/* Segoe UI is the default UI font for Vista and later, and
|
||||
* is used by the Win L&F which is used by FX too.
|
||||
* Tahoma is used for the Win L&F on XP.
|
||||
* Verdana is used in some FX UI controls.
|
||||
*/
|
||||
fd = new FamilyDescription();
|
||||
fd.familyName = "Segoe UI";
|
||||
fd.plainFullName = "Segoe UI";
|
||||
fd.plainFileName = "segoeui.ttf";
|
||||
fd.boldFullName = "Segoe UI Bold";
|
||||
fd.boldFileName = "segoeuib.ttf";
|
||||
fd.italicFullName = "Segoe UI Italic";
|
||||
fd.italicFileName = "segoeuii.ttf";
|
||||
fd.boldItalicFullName = "Segoe UI Bold Italic";
|
||||
fd.boldItalicFileName = "segoeuiz.ttf";
|
||||
platformFontMap.put("segoe", fd);
|
||||
|
||||
fd = new FamilyDescription();
|
||||
fd.familyName = "Tahoma";
|
||||
fd.plainFullName = "Tahoma";
|
||||
fd.plainFileName = "tahoma.ttf";
|
||||
fd.boldFullName = "Tahoma Bold";
|
||||
fd.boldFileName = "tahomabd.ttf";
|
||||
platformFontMap.put("tahoma", fd);
|
||||
|
||||
fd = new FamilyDescription();
|
||||
fd.familyName = "Verdana";
|
||||
fd.plainFullName = "Verdana";
|
||||
fd.plainFileName = "verdana.TTF";
|
||||
fd.boldFullName = "Verdana Bold";
|
||||
fd.boldFileName = "verdanab.TTF";
|
||||
fd.italicFullName = "Verdana Italic";
|
||||
fd.italicFileName = "verdanai.TTF";
|
||||
fd.boldItalicFullName = "Verdana Bold Italic";
|
||||
fd.boldItalicFileName = "verdanaz.TTF";
|
||||
platformFontMap.put("verdana", fd);
|
||||
|
||||
/* The following are important because they are the core
|
||||
* members of the default "Dialog" font.
|
||||
*/
|
||||
fd = new FamilyDescription();
|
||||
fd.familyName = "Arial";
|
||||
fd.plainFullName = "Arial";
|
||||
fd.plainFileName = "ARIAL.TTF";
|
||||
fd.boldFullName = "Arial Bold";
|
||||
fd.boldFileName = "ARIALBD.TTF";
|
||||
fd.italicFullName = "Arial Italic";
|
||||
fd.italicFileName = "ARIALI.TTF";
|
||||
fd.boldItalicFullName = "Arial Bold Italic";
|
||||
fd.boldItalicFileName = "ARIALBI.TTF";
|
||||
platformFontMap.put("arial", fd);
|
||||
|
||||
fd = new FamilyDescription();
|
||||
fd.familyName = "Symbol";
|
||||
fd.plainFullName = "Symbol";
|
||||
fd.plainFileName = "Symbol.TTF";
|
||||
platformFontMap.put("symbol", fd);
|
||||
|
||||
fd = new FamilyDescription();
|
||||
fd.familyName = "WingDings";
|
||||
fd.plainFullName = "WingDings";
|
||||
fd.plainFileName = "WINGDING.TTF";
|
||||
platformFontMap.put("wingdings", fd);
|
||||
|
||||
return platformFontMap;
|
||||
}
|
||||
}
|
||||
340
jdkSrc/jdk8/sun/awt/Win32GraphicsConfig.java
Normal file
340
jdkSrc/jdk8/sun/awt/Win32GraphicsConfig.java
Normal file
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2009, 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;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.BufferCapabilities;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.ImageCapabilities;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.Window;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.VolatileImage;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
import sun.awt.windows.WComponentPeer;
|
||||
import sun.awt.image.OffScreenImage;
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.image.SurfaceManager;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.InvalidPipeException;
|
||||
import sun.java2d.loops.RenderLoops;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import sun.java2d.windows.GDIWindowSurfaceData;
|
||||
|
||||
/**
|
||||
* This is an implementation of a GraphicsConfiguration object for a
|
||||
* single Win32 visual.
|
||||
*
|
||||
* @see GraphicsEnvironment
|
||||
* @see GraphicsDevice
|
||||
*/
|
||||
public class Win32GraphicsConfig extends GraphicsConfiguration
|
||||
implements DisplayChangedListener, SurfaceManager.ProxiedGraphicsConfig
|
||||
{
|
||||
protected Win32GraphicsDevice screen;
|
||||
protected int visual; //PixelFormatID
|
||||
protected RenderLoops solidloops;
|
||||
|
||||
private static native void initIDs();
|
||||
|
||||
static {
|
||||
initIDs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Win32GraphicsConfiguration object with the given device
|
||||
* and PixelFormat. Note that this method does NOT check to ensure that
|
||||
* the returned Win32GraphicsConfig will correctly support rendering into a
|
||||
* Java window. This method is provided so that client code can do its
|
||||
* own checking as to the appropriateness of a particular PixelFormat.
|
||||
* Safer access to Win32GraphicsConfigurations is provided by
|
||||
* Win32GraphicsDevice.getConfigurations().
|
||||
*/
|
||||
public static Win32GraphicsConfig getConfig(Win32GraphicsDevice device,
|
||||
int pixFormatID)
|
||||
{
|
||||
return new Win32GraphicsConfig(device, pixFormatID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of JDK version 1.3
|
||||
* replaced by <code>getConfig()</code>
|
||||
*/
|
||||
@Deprecated
|
||||
public Win32GraphicsConfig(GraphicsDevice device, int visualnum) {
|
||||
this.screen = (Win32GraphicsDevice)device;
|
||||
this.visual = visualnum;
|
||||
((Win32GraphicsDevice)device).addDisplayChangedListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the graphics device associated with this configuration.
|
||||
*/
|
||||
public GraphicsDevice getDevice() {
|
||||
return screen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the PixelFormatIndex this GraphicsConfig uses
|
||||
*/
|
||||
public int getVisual() {
|
||||
return visual;
|
||||
}
|
||||
|
||||
public Object getProxyKey() {
|
||||
return screen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the RenderLoops this type of destination uses for
|
||||
* solid fills and strokes.
|
||||
*/
|
||||
private SurfaceType sTypeOrig = null;
|
||||
public synchronized RenderLoops getSolidLoops(SurfaceType stype) {
|
||||
if (solidloops == null || sTypeOrig != stype) {
|
||||
solidloops = SurfaceData.makeRenderLoops(SurfaceType.OpaqueColor,
|
||||
CompositeType.SrcNoEa,
|
||||
stype);
|
||||
sTypeOrig = stype;
|
||||
}
|
||||
return solidloops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color model associated with this configuration.
|
||||
*/
|
||||
public synchronized ColorModel getColorModel() {
|
||||
return screen.getColorModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new color model for this configuration. This call
|
||||
* is only used internally, by images and components that are
|
||||
* associated with the graphics device. When attributes of that
|
||||
* device change (for example, when the device palette is updated),
|
||||
* then this device-based color model will be updated internally
|
||||
* to reflect the new situation.
|
||||
*/
|
||||
public ColorModel getDeviceColorModel() {
|
||||
return screen.getDynamicColorModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color model associated with this configuration that
|
||||
* supports the specified transparency.
|
||||
*/
|
||||
public ColorModel getColorModel(int transparency) {
|
||||
switch (transparency) {
|
||||
case Transparency.OPAQUE:
|
||||
return getColorModel();
|
||||
case Transparency.BITMASK:
|
||||
return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
|
||||
case Transparency.TRANSLUCENT:
|
||||
return ColorModel.getRGBdefault();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default Transform for this configuration. This
|
||||
* Transform is typically the Identity transform for most normal
|
||||
* screens. Device coordinates for screen and printer devices will
|
||||
* have the origin in the upper left-hand corner of the target region of
|
||||
* the device, with X coordinates
|
||||
* increasing to the right and Y coordinates increasing downwards.
|
||||
* For image buffers, this Transform will be the Identity transform.
|
||||
*/
|
||||
public AffineTransform getDefaultTransform() {
|
||||
return new AffineTransform();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns a Transform that can be composed with the default Transform
|
||||
* of a Graphics2D so that 72 units in user space will equal 1 inch
|
||||
* in device space.
|
||||
* Given a Graphics2D, g, one can reset the transformation to create
|
||||
* such a mapping by using the following pseudocode:
|
||||
* <pre>
|
||||
* GraphicsConfiguration gc = g.getGraphicsConfiguration();
|
||||
*
|
||||
* g.setTransform(gc.getDefaultTransform());
|
||||
* g.transform(gc.getNormalizingTransform());
|
||||
* </pre>
|
||||
* Note that sometimes this Transform will be identity (e.g. for
|
||||
* printers or metafile output) and that this Transform is only
|
||||
* as accurate as the information supplied by the underlying system.
|
||||
* For image buffers, this Transform will be the Identity transform,
|
||||
* since there is no valid distance measurement.
|
||||
*/
|
||||
public AffineTransform getNormalizingTransform() {
|
||||
Win32GraphicsEnvironment ge = (Win32GraphicsEnvironment)
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
double xscale = ge.getXResolution() / 72.0;
|
||||
double yscale = ge.getYResolution() / 72.0;
|
||||
return new AffineTransform(xscale, 0.0, 0.0, yscale, 0.0, 0.0);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return (super.toString()+"[dev="+screen+",pixfmt="+visual+"]");
|
||||
}
|
||||
|
||||
private native Rectangle getBounds(int screen);
|
||||
|
||||
public Rectangle getBounds() {
|
||||
return getBounds(screen.getScreen());
|
||||
}
|
||||
|
||||
public synchronized void displayChanged() {
|
||||
solidloops = null;
|
||||
}
|
||||
|
||||
public void paletteChanged() {}
|
||||
|
||||
/**
|
||||
* The following methods are invoked from WComponentPeer.java rather
|
||||
* than having the Win32-dependent implementations hardcoded in that
|
||||
* class. This way the appropriate actions are taken based on the peer's
|
||||
* GraphicsConfig, whether it is a Win32GraphicsConfig or a
|
||||
* WGLGraphicsConfig.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a new SurfaceData that will be associated with the given
|
||||
* WComponentPeer.
|
||||
*/
|
||||
public SurfaceData createSurfaceData(WComponentPeer peer,
|
||||
int numBackBuffers)
|
||||
{
|
||||
return GDIWindowSurfaceData.createData(peer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new managed image of the given width and height
|
||||
* that is associated with the target Component.
|
||||
*/
|
||||
public Image createAcceleratedImage(Component target,
|
||||
int width, int height)
|
||||
{
|
||||
ColorModel model = getColorModel(Transparency.OPAQUE);
|
||||
WritableRaster wr =
|
||||
model.createCompatibleWritableRaster(width, height);
|
||||
return new OffScreenImage(target, model, wr,
|
||||
model.isAlphaPremultiplied());
|
||||
}
|
||||
|
||||
/**
|
||||
* The following methods correspond to the multibuffering methods in
|
||||
* WComponentPeer.java...
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks that the requested configuration is natively supported; if not,
|
||||
* an AWTException is thrown.
|
||||
*/
|
||||
public void assertOperationSupported(Component target,
|
||||
int numBuffers,
|
||||
BufferCapabilities caps)
|
||||
throws AWTException
|
||||
{
|
||||
// the default pipeline doesn't support flip buffer strategy
|
||||
throw new AWTException(
|
||||
"The operation requested is not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from WComponentPeer when a surface data is replaced
|
||||
* REMIND: while the default pipeline doesn't support flipping, it may
|
||||
* happen that the accelerated device may have this graphics config
|
||||
* (like if the device restoration failed when one device exits fs mode
|
||||
* while others remain).
|
||||
*/
|
||||
public VolatileImage createBackBuffer(WComponentPeer peer) {
|
||||
Component target = (Component)peer.getTarget();
|
||||
return new SunVolatileImage(target,
|
||||
target.getWidth(), target.getHeight(),
|
||||
Boolean.TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the native flip operation for the given target Component.
|
||||
*
|
||||
* REMIND: we should really not get here because that would mean that
|
||||
* a FLIP BufferStrategy has been created, and one could only be created
|
||||
* if accelerated pipeline is present but in some rare (and transitional)
|
||||
* cases it may happen that the accelerated graphics device may have a
|
||||
* default graphics configuraiton, so this is just a precaution.
|
||||
*/
|
||||
public void flip(WComponentPeer peer,
|
||||
Component target, VolatileImage backBuffer,
|
||||
int x1, int y1, int x2, int y2,
|
||||
BufferCapabilities.FlipContents flipAction)
|
||||
{
|
||||
if (flipAction == BufferCapabilities.FlipContents.COPIED ||
|
||||
flipAction == BufferCapabilities.FlipContents.UNDEFINED) {
|
||||
Graphics g = peer.getGraphics();
|
||||
try {
|
||||
g.drawImage(backBuffer,
|
||||
x1, y1, x2, y2,
|
||||
x1, y1, x2, y2,
|
||||
null);
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
} else if (flipAction == BufferCapabilities.FlipContents.BACKGROUND) {
|
||||
Graphics g = backBuffer.getGraphics();
|
||||
try {
|
||||
g.setColor(target.getBackground());
|
||||
g.fillRect(0, 0,
|
||||
backBuffer.getWidth(),
|
||||
backBuffer.getHeight());
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
// the rest of the flip actions are not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTranslucencyCapable() {
|
||||
//XXX: worth checking if 8-bit? Anyway, it doesn't hurt.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
637
jdkSrc/jdk8/sun/awt/Win32GraphicsDevice.java
Normal file
637
jdkSrc/jdk8/sun/awt/Win32GraphicsDevice.java
Normal file
@@ -0,0 +1,637 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, 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;
|
||||
|
||||
import java.awt.AWTPermission;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.DisplayMode;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Vector;
|
||||
import java.awt.peer.WindowPeer;
|
||||
import sun.awt.windows.WWindowPeer;
|
||||
import sun.java2d.opengl.WGLGraphicsConfig;
|
||||
import sun.java2d.windows.WindowsFlags;
|
||||
|
||||
/**
|
||||
* This is an implementation of a GraphicsDevice object for a single
|
||||
* Win32 screen.
|
||||
*
|
||||
* @see GraphicsEnvironment
|
||||
* @see GraphicsConfiguration
|
||||
*/
|
||||
public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
DisplayChangedListener {
|
||||
int screen;
|
||||
ColorModel dynamicColorModel; // updated with dev changes
|
||||
ColorModel colorModel; // static for device
|
||||
protected GraphicsConfiguration[] configs;
|
||||
protected GraphicsConfiguration defaultConfig;
|
||||
|
||||
private final String idString;
|
||||
protected String descString;
|
||||
// Note that we do not synchronize access to this variable - it doesn't
|
||||
// really matter if a thread does an operation on graphics device which is
|
||||
// about to become invalid (or already become) - we are prepared to deal
|
||||
// with this on the native level.
|
||||
private boolean valid;
|
||||
|
||||
// keep track of top-level windows on this display
|
||||
private SunDisplayChanger topLevels = new SunDisplayChanger();
|
||||
// REMIND: we may disable the use of pixel formats for some accelerated
|
||||
// pipelines which are mutually exclusive with opengl, for which
|
||||
// pixel formats were added in the first place
|
||||
protected static boolean pfDisabled;
|
||||
private static AWTPermission fullScreenExclusivePermission;
|
||||
// the original display mode we had before entering the fullscreen
|
||||
// mode
|
||||
private DisplayMode defaultDisplayMode;
|
||||
// activation/deactivation listener for the full-screen window
|
||||
private WindowListener fsWindowListener;
|
||||
|
||||
static {
|
||||
|
||||
// 4455041 - Even when ddraw is disabled, ddraw.dll is loaded when
|
||||
// pixel format calls are made. This causes problems when a Java app
|
||||
// is run as an NT service. To prevent the loading of ddraw.dll
|
||||
// completely, sun.awt.nopixfmt should be set as well. Apps which use
|
||||
// OpenGL w/ Java probably don't want to set this.
|
||||
String nopixfmt = (String)java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("sun.awt.nopixfmt"));
|
||||
pfDisabled = (nopixfmt != null);
|
||||
initIDs();
|
||||
}
|
||||
|
||||
private static native void initIDs();
|
||||
|
||||
native void initDevice(int screen);
|
||||
|
||||
public Win32GraphicsDevice(int screennum) {
|
||||
this.screen = screennum;
|
||||
// we cache the strings because we want toString() and getIDstring
|
||||
// to reflect the original screen number (which may change if the
|
||||
// device is removed)
|
||||
idString = "\\Display"+screen;
|
||||
// REMIND: may be should use class name?
|
||||
descString = "Win32GraphicsDevice[screen=" + screen;
|
||||
valid = true;
|
||||
|
||||
initDevice(screennum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the graphics device.
|
||||
* @see #TYPE_RASTER_SCREEN
|
||||
* @see #TYPE_PRINTER
|
||||
* @see #TYPE_IMAGE_BUFFER
|
||||
*/
|
||||
public int getType() {
|
||||
return TYPE_RASTER_SCREEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Win32 screen of the device.
|
||||
*/
|
||||
public int getScreen() {
|
||||
return screen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this is a valid devicie. Device can become
|
||||
* invalid as a result of device removal event.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from native code when the device was removed.
|
||||
*
|
||||
* @param defaultScreen the current default screen
|
||||
*/
|
||||
protected void invalidate(int defaultScreen) {
|
||||
valid = false;
|
||||
screen = defaultScreen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identification string associated with this graphics
|
||||
* device.
|
||||
*/
|
||||
public String getIDstring() {
|
||||
return idString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all of the graphics
|
||||
* configurations associated with this graphics device.
|
||||
*/
|
||||
public GraphicsConfiguration[] getConfigurations() {
|
||||
if (configs==null) {
|
||||
if (WindowsFlags.isOGLEnabled() && isDefaultDevice()) {
|
||||
defaultConfig = getDefaultConfiguration();
|
||||
if (defaultConfig != null) {
|
||||
configs = new GraphicsConfiguration[1];
|
||||
configs[0] = defaultConfig;
|
||||
return configs.clone();
|
||||
}
|
||||
}
|
||||
|
||||
int max = getMaxConfigs(screen);
|
||||
int defaultPixID = getDefaultPixID(screen);
|
||||
Vector v = new Vector( max );
|
||||
if (defaultPixID == 0) {
|
||||
// Workaround for failing GDI calls
|
||||
defaultConfig = Win32GraphicsConfig.getConfig(this,
|
||||
defaultPixID);
|
||||
v.addElement(defaultConfig);
|
||||
}
|
||||
else {
|
||||
for (int i = 1; i <= max; i++) {
|
||||
if (isPixFmtSupported(i, screen)) {
|
||||
if (i == defaultPixID) {
|
||||
defaultConfig = Win32GraphicsConfig.getConfig(
|
||||
this, i);
|
||||
v.addElement(defaultConfig);
|
||||
}
|
||||
else {
|
||||
v.addElement(Win32GraphicsConfig.getConfig(
|
||||
this, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
configs = new GraphicsConfiguration[v.size()];
|
||||
v.copyInto(configs);
|
||||
}
|
||||
return configs.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of graphics configurations available, or 1
|
||||
* if PixelFormat calls fail or are disabled.
|
||||
* This number is less than or equal to the number of graphics
|
||||
* configurations supported.
|
||||
*/
|
||||
protected int getMaxConfigs(int screen) {
|
||||
if (pfDisabled) {
|
||||
return 1;
|
||||
} else {
|
||||
return getMaxConfigsImpl(screen);
|
||||
}
|
||||
}
|
||||
|
||||
private native int getMaxConfigsImpl(int screen);
|
||||
|
||||
/**
|
||||
* Returns whether or not the PixelFormat indicated by index is
|
||||
* supported. Supported PixelFormats support drawing to a Window
|
||||
* (PFD_DRAW_TO_WINDOW), support GDI (PFD_SUPPORT_GDI), and in the
|
||||
* case of an 8-bit format (cColorBits <= 8) uses indexed colors
|
||||
* (iPixelType == PFD_TYPE_COLORINDEX).
|
||||
* We use the index 0 to indicate that PixelFormat calls don't work, or
|
||||
* are disabled. Do not call this function with an index of 0.
|
||||
* @param index a PixelFormat index
|
||||
*/
|
||||
protected native boolean isPixFmtSupported(int index, int screen);
|
||||
|
||||
/**
|
||||
* Returns the PixelFormatID of the default graphics configuration
|
||||
* associated with this graphics device, or 0 if PixelFormats calls fail or
|
||||
* are disabled.
|
||||
*/
|
||||
protected int getDefaultPixID(int screen) {
|
||||
if (pfDisabled) {
|
||||
return 0;
|
||||
} else {
|
||||
return getDefaultPixIDImpl(screen);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default PixelFormat ID from GDI. Do not call if PixelFormats
|
||||
* are disabled.
|
||||
*/
|
||||
private native int getDefaultPixIDImpl(int screen);
|
||||
|
||||
/**
|
||||
* Returns the default graphics configuration
|
||||
* associated with this graphics device.
|
||||
*/
|
||||
public GraphicsConfiguration getDefaultConfiguration() {
|
||||
if (defaultConfig == null) {
|
||||
// first try to create a WGLGraphicsConfig if OGL is enabled
|
||||
// REMIND: the WGL code does not yet work properly in multimon
|
||||
// situations, so we will fallback on GDI if we are not on the
|
||||
// default device...
|
||||
if (WindowsFlags.isOGLEnabled() && isDefaultDevice()) {
|
||||
int defPixID = WGLGraphicsConfig.getDefaultPixFmt(screen);
|
||||
defaultConfig = WGLGraphicsConfig.getConfig(this, defPixID);
|
||||
if (WindowsFlags.isOGLVerbose()) {
|
||||
if (defaultConfig != null) {
|
||||
System.out.print("OpenGL pipeline enabled");
|
||||
} else {
|
||||
System.out.print("Could not enable OpenGL pipeline");
|
||||
}
|
||||
System.out.println(" for default config on screen " +
|
||||
screen);
|
||||
}
|
||||
}
|
||||
|
||||
// Fix for 4669614. Most apps are not concerned with PixelFormats,
|
||||
// yet we ALWAYS used them for determining ColorModels and such.
|
||||
// By passing in 0 as the PixelFormatID here, we signal that
|
||||
// PixelFormats should not be used, thus avoid loading the opengl
|
||||
// library. Apps concerned with PixelFormats can still use
|
||||
// GraphicsConfiguration.getConfigurations().
|
||||
// Note that calling native pixel format functions tends to cause
|
||||
// problems between those functions (which are OpenGL-related)
|
||||
// and our use of DirectX. For example, some Matrox boards will
|
||||
// crash or hang calling these functions when any app is running
|
||||
// in DirectX fullscreen mode. So avoiding these calls unless
|
||||
// absolutely necessary is preferable.
|
||||
if (defaultConfig == null) {
|
||||
defaultConfig = Win32GraphicsConfig.getConfig(this, 0);
|
||||
}
|
||||
}
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return valid ? descString + "]" : descString + ", removed]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is the default GraphicsDevice for the
|
||||
* GraphicsEnvironment.
|
||||
*/
|
||||
private boolean isDefaultDevice() {
|
||||
return (this ==
|
||||
GraphicsEnvironment.
|
||||
getLocalGraphicsEnvironment().getDefaultScreenDevice());
|
||||
}
|
||||
|
||||
private static boolean isFSExclusiveModeAllowed() {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
if (fullScreenExclusivePermission == null) {
|
||||
fullScreenExclusivePermission =
|
||||
new AWTPermission("fullScreenExclusive");
|
||||
}
|
||||
try {
|
||||
security.checkPermission(fullScreenExclusivePermission);
|
||||
} catch (SecurityException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true unless we're not allowed to use fullscreen mode.
|
||||
*/
|
||||
@Override
|
||||
public boolean isFullScreenSupported() {
|
||||
return isFSExclusiveModeAllowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setFullScreenWindow(Window w) {
|
||||
Window old = getFullScreenWindow();
|
||||
if (w == old) {
|
||||
return;
|
||||
}
|
||||
if (!isFullScreenSupported()) {
|
||||
super.setFullScreenWindow(w);
|
||||
return;
|
||||
}
|
||||
|
||||
// Enter windowed mode.
|
||||
if (old != null) {
|
||||
// restore the original display mode
|
||||
if (defaultDisplayMode != null) {
|
||||
setDisplayMode(defaultDisplayMode);
|
||||
// we set the default display mode to null here
|
||||
// because the default mode could change during
|
||||
// the life of the application (user can change it through
|
||||
// the desktop properties dialog, for example), so
|
||||
// we need to record it every time prior to
|
||||
// entering the fullscreen mode.
|
||||
defaultDisplayMode = null;
|
||||
}
|
||||
WWindowPeer peer = (WWindowPeer)old.getPeer();
|
||||
if (peer != null) {
|
||||
peer.setFullScreenExclusiveModeState(false);
|
||||
// we used to destroy the buffers on exiting fs mode, this
|
||||
// is no longer needed since fs change will cause a surface
|
||||
// data replacement
|
||||
synchronized(peer) {
|
||||
exitFullScreenExclusive(screen, peer);
|
||||
}
|
||||
}
|
||||
removeFSWindowListener(old);
|
||||
}
|
||||
super.setFullScreenWindow(w);
|
||||
if (w != null) {
|
||||
// always record the default display mode prior to going
|
||||
// fullscreen
|
||||
defaultDisplayMode = getDisplayMode();
|
||||
addFSWindowListener(w);
|
||||
// Enter full screen exclusive mode.
|
||||
WWindowPeer peer = (WWindowPeer)w.getPeer();
|
||||
if (peer != null) {
|
||||
synchronized(peer) {
|
||||
enterFullScreenExclusive(screen, peer);
|
||||
// Note: removed replaceSurfaceData() call because
|
||||
// changing the window size or making it visible
|
||||
// will cause this anyway, and both of these events happen
|
||||
// as part of switching into fullscreen mode.
|
||||
}
|
||||
peer.setFullScreenExclusiveModeState(true);
|
||||
}
|
||||
|
||||
// fix for 4868278
|
||||
peer.updateGC();
|
||||
}
|
||||
}
|
||||
|
||||
// Entering and exiting full-screen mode are done within a
|
||||
// tree-lock and should never lock on any resources which are
|
||||
// required by other threads which may have them and may require
|
||||
// the tree-lock.
|
||||
// REMIND: in the future these methods may need to become protected so that
|
||||
// subclasses could override them and use appropriate api other than GDI
|
||||
// for implementing these functions.
|
||||
protected native void enterFullScreenExclusive(int screen, WindowPeer w);
|
||||
protected native void exitFullScreenExclusive(int screen, WindowPeer w);
|
||||
|
||||
@Override
|
||||
public boolean isDisplayChangeSupported() {
|
||||
return (isFullScreenSupported() && getFullScreenWindow() != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setDisplayMode(DisplayMode dm) {
|
||||
if (!isDisplayChangeSupported()) {
|
||||
super.setDisplayMode(dm);
|
||||
return;
|
||||
}
|
||||
if (dm == null || (dm = getMatchingDisplayMode(dm)) == null) {
|
||||
throw new IllegalArgumentException("Invalid display mode");
|
||||
}
|
||||
if (getDisplayMode().equals(dm)) {
|
||||
return;
|
||||
}
|
||||
Window w = getFullScreenWindow();
|
||||
if (w != null) {
|
||||
WWindowPeer peer = (WWindowPeer)w.getPeer();
|
||||
configDisplayMode(screen, peer, dm.getWidth(), dm.getHeight(),
|
||||
dm.getBitDepth(), dm.getRefreshRate());
|
||||
// resize the fullscreen window to the dimensions of the new
|
||||
// display mode
|
||||
Rectangle screenBounds = getDefaultConfiguration().getBounds();
|
||||
w.setBounds(screenBounds.x, screenBounds.y,
|
||||
dm.getWidth(), dm.getHeight());
|
||||
// Note: no call to replaceSurfaceData is required here since
|
||||
// replacement will be caused by an upcoming display change event
|
||||
} else {
|
||||
throw new IllegalStateException("Must be in fullscreen mode " +
|
||||
"in order to set display mode");
|
||||
}
|
||||
}
|
||||
|
||||
protected native DisplayMode getCurrentDisplayMode(int screen);
|
||||
protected native void configDisplayMode(int screen, WindowPeer w, int width,
|
||||
int height, int bitDepth,
|
||||
int refreshRate);
|
||||
protected native void enumDisplayModes(int screen, ArrayList modes);
|
||||
|
||||
@Override
|
||||
public synchronized DisplayMode getDisplayMode() {
|
||||
DisplayMode res = getCurrentDisplayMode(screen);
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized DisplayMode[] getDisplayModes() {
|
||||
ArrayList modes = new ArrayList();
|
||||
enumDisplayModes(screen, modes);
|
||||
int listSize = modes.size();
|
||||
DisplayMode[] retArray = new DisplayMode[listSize];
|
||||
for (int i = 0; i < listSize; i++) {
|
||||
retArray[i] = (DisplayMode)modes.get(i);
|
||||
}
|
||||
return retArray;
|
||||
}
|
||||
|
||||
protected synchronized DisplayMode getMatchingDisplayMode(DisplayMode dm) {
|
||||
if (!isDisplayChangeSupported()) {
|
||||
return null;
|
||||
}
|
||||
DisplayMode[] modes = getDisplayModes();
|
||||
for (DisplayMode mode : modes) {
|
||||
if (dm.equals(mode) ||
|
||||
(dm.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN &&
|
||||
dm.getWidth() == mode.getWidth() &&
|
||||
dm.getHeight() == mode.getHeight() &&
|
||||
dm.getBitDepth() == mode.getBitDepth()))
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* From the DisplayChangeListener interface.
|
||||
* Called from Win32GraphicsEnvironment when the display settings have
|
||||
* changed.
|
||||
*/
|
||||
public void displayChanged() {
|
||||
dynamicColorModel = null;
|
||||
defaultConfig = null;
|
||||
configs = null;
|
||||
// pass on to all top-level windows on this display
|
||||
topLevels.notifyListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the DisplayChangedListener interface: devices
|
||||
* do not need to react to this event
|
||||
*/
|
||||
public void paletteChanged() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a DisplayChangeListener to be notified when the display settings
|
||||
* are changed. Typically, only top-level containers need to be added
|
||||
* to Win32GraphicsDevice.
|
||||
*/
|
||||
public void addDisplayChangedListener(DisplayChangedListener client) {
|
||||
topLevels.add(client);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a DisplayChangeListener from this Win32GraphicsDevice
|
||||
*/
|
||||
public void removeDisplayChangedListener(DisplayChangedListener client) {
|
||||
topLevels.remove(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the color model associated with this device
|
||||
*/
|
||||
private native ColorModel makeColorModel (int screen,
|
||||
boolean dynamic);
|
||||
|
||||
/**
|
||||
* Returns a dynamic ColorModel which is updated when there
|
||||
* are any changes (e.g., palette changes) in the device
|
||||
*/
|
||||
public ColorModel getDynamicColorModel() {
|
||||
if (dynamicColorModel == null) {
|
||||
dynamicColorModel = makeColorModel(screen, true);
|
||||
}
|
||||
return dynamicColorModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the non-dynamic ColorModel associated with this device
|
||||
*/
|
||||
public ColorModel getColorModel() {
|
||||
if (colorModel == null) {
|
||||
colorModel = makeColorModel(screen, false);
|
||||
}
|
||||
return colorModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* WindowAdapter class responsible for de/iconifying full-screen window
|
||||
* of this device.
|
||||
*
|
||||
* The listener restores the default display mode when window is iconified
|
||||
* and sets it back to the one set by the user on de-iconification.
|
||||
*/
|
||||
private static class Win32FSWindowAdapter extends WindowAdapter {
|
||||
private Win32GraphicsDevice device;
|
||||
private DisplayMode dm;
|
||||
|
||||
Win32FSWindowAdapter(Win32GraphicsDevice device) {
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
private void setFSWindowsState(Window other, int state) {
|
||||
GraphicsDevice gds[] =
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment().
|
||||
getScreenDevices();
|
||||
// check if the de/activation was caused by other
|
||||
// fs window and ignore the event if that's the case
|
||||
if (other != null) {
|
||||
for (GraphicsDevice gd : gds) {
|
||||
if (other == gd.getFullScreenWindow()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// otherwise apply state to all fullscreen windows
|
||||
for (GraphicsDevice gd : gds) {
|
||||
Window fsw = gd.getFullScreenWindow();
|
||||
if (fsw instanceof Frame) {
|
||||
((Frame)fsw).setExtendedState(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated(WindowEvent e) {
|
||||
setFSWindowsState(e.getOppositeWindow(), Frame.ICONIFIED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowActivated(WindowEvent e) {
|
||||
setFSWindowsState(e.getOppositeWindow(), Frame.NORMAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowIconified(WindowEvent e) {
|
||||
// restore the default display mode for this device
|
||||
DisplayMode ddm = device.defaultDisplayMode;
|
||||
if (ddm != null) {
|
||||
dm = device.getDisplayMode();
|
||||
device.setDisplayMode(ddm);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeiconified(WindowEvent e) {
|
||||
// restore the user-set display mode for this device
|
||||
if (dm != null) {
|
||||
device.setDisplayMode(dm);
|
||||
dm = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a WindowListener to be used as
|
||||
* activation/deactivation listener for the current full-screen window.
|
||||
*
|
||||
* @param w full-screen window
|
||||
*/
|
||||
protected void addFSWindowListener(final Window w) {
|
||||
// Note: even though we create a listener for Window instances of
|
||||
// fs windows they will not receive window events.
|
||||
fsWindowListener = new Win32FSWindowAdapter(this);
|
||||
|
||||
// Fix for 6709453. Using invokeLater to avoid listening
|
||||
// for the events already posted to the queue.
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
w.addWindowListener(fsWindowListener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the fs window listener.
|
||||
*
|
||||
* @param w full-screen window
|
||||
*/
|
||||
protected void removeFSWindowListener(Window w) {
|
||||
w.removeWindowListener(fsWindowListener);
|
||||
fsWindowListener = null;
|
||||
}
|
||||
}
|
||||
267
jdkSrc/jdk8/sun/awt/Win32GraphicsEnvironment.java
Normal file
267
jdkSrc/jdk8/sun/awt/Win32GraphicsEnvironment.java
Normal file
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, 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;
|
||||
|
||||
import java.awt.AWTError;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.ListIterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.StringTokenizer;
|
||||
import sun.awt.DisplayChangedListener;
|
||||
import sun.awt.SunDisplayChanger;
|
||||
import sun.awt.windows.WPrinterJob;
|
||||
import sun.awt.windows.WToolkit;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import sun.java2d.SurfaceManagerFactory;
|
||||
import sun.java2d.WindowsSurfaceManagerFactory;
|
||||
import sun.java2d.d3d.D3DGraphicsDevice;
|
||||
import sun.java2d.windows.WindowsFlags;
|
||||
|
||||
/**
|
||||
* This is an implementation of a GraphicsEnvironment object for the
|
||||
* default local GraphicsEnvironment used by the Java Runtime Environment
|
||||
* for Windows.
|
||||
*
|
||||
* @see GraphicsDevice
|
||||
* @see GraphicsConfiguration
|
||||
*/
|
||||
|
||||
public class Win32GraphicsEnvironment
|
||||
extends SunGraphicsEnvironment
|
||||
{
|
||||
static {
|
||||
// Ensure awt is loaded already. Also, this forces static init
|
||||
// of WToolkit and Toolkit, which we depend upon
|
||||
WToolkit.loadLibraries();
|
||||
// setup flags before initializing native layer
|
||||
WindowsFlags.initFlags();
|
||||
initDisplayWrapper();
|
||||
|
||||
// Install correct surface manager factory.
|
||||
SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes native components of the graphics environment. This
|
||||
* includes everything from the native GraphicsDevice elements to
|
||||
* the DirectX rendering layer.
|
||||
*/
|
||||
private static native void initDisplay();
|
||||
|
||||
private static boolean displayInitialized; // = false;
|
||||
public static void initDisplayWrapper() {
|
||||
if (!displayInitialized) {
|
||||
displayInitialized = true;
|
||||
initDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
public Win32GraphicsEnvironment() {
|
||||
}
|
||||
|
||||
protected native int getNumScreens();
|
||||
protected native int getDefaultScreen();
|
||||
|
||||
public GraphicsDevice getDefaultScreenDevice() {
|
||||
GraphicsDevice[] screens = getScreenDevices();
|
||||
if (screens.length == 0) {
|
||||
throw new AWTError("no screen devices");
|
||||
}
|
||||
int index = getDefaultScreen();
|
||||
return screens[0 < index && index < screens.length ? index : 0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of pixels per logical inch along the screen width.
|
||||
* In a system with multiple display monitors, this value is the same for
|
||||
* all monitors.
|
||||
* @returns number of pixels per logical inch in X direction
|
||||
*/
|
||||
public native int getXResolution();
|
||||
/**
|
||||
* Returns the number of pixels per logical inch along the screen height.
|
||||
* In a system with multiple display monitors, this value is the same for
|
||||
* all monitors.
|
||||
* @returns number of pixels per logical inch in Y direction
|
||||
*/
|
||||
public native int getYResolution();
|
||||
|
||||
|
||||
/*
|
||||
* ----DISPLAY CHANGE SUPPORT----
|
||||
*/
|
||||
|
||||
// list of invalidated graphics devices (those which were removed)
|
||||
private ArrayList<WeakReference<Win32GraphicsDevice>> oldDevices;
|
||||
/*
|
||||
* From DisplayChangeListener interface.
|
||||
* Called from WToolkit and executed on the event thread when the
|
||||
* display settings are changed.
|
||||
*/
|
||||
@Override
|
||||
public void displayChanged() {
|
||||
// getNumScreens() will return the correct current number of screens
|
||||
GraphicsDevice newDevices[] = new GraphicsDevice[getNumScreens()];
|
||||
GraphicsDevice oldScreens[] = screens;
|
||||
// go through the list of current devices and determine if they
|
||||
// could be reused, or will have to be replaced
|
||||
if (oldScreens != null) {
|
||||
for (int i = 0; i < oldScreens.length; i++) {
|
||||
if (!(screens[i] instanceof Win32GraphicsDevice)) {
|
||||
// REMIND: can we ever have anything other than Win32GD?
|
||||
assert (false) : oldScreens[i];
|
||||
continue;
|
||||
}
|
||||
Win32GraphicsDevice gd = (Win32GraphicsDevice)oldScreens[i];
|
||||
// devices may be invalidated from the native code when the
|
||||
// display change happens (device add/removal also causes a
|
||||
// display change)
|
||||
if (!gd.isValid()) {
|
||||
if (oldDevices == null) {
|
||||
oldDevices =
|
||||
new ArrayList<WeakReference<Win32GraphicsDevice>>();
|
||||
}
|
||||
oldDevices.add(new WeakReference<Win32GraphicsDevice>(gd));
|
||||
} else if (i < newDevices.length) {
|
||||
// reuse the device
|
||||
newDevices[i] = gd;
|
||||
}
|
||||
}
|
||||
oldScreens = null;
|
||||
}
|
||||
// create the new devices (those that weren't reused)
|
||||
for (int i = 0; i < newDevices.length; i++) {
|
||||
if (newDevices[i] == null) {
|
||||
newDevices[i] = makeScreenDevice(i);
|
||||
}
|
||||
}
|
||||
// install the new array of devices
|
||||
// Note: no synchronization here, it doesn't matter if a thread gets
|
||||
// a new or an old array this time around
|
||||
screens = newDevices;
|
||||
for (GraphicsDevice gd : screens) {
|
||||
if (gd instanceof DisplayChangedListener) {
|
||||
((DisplayChangedListener)gd).displayChanged();
|
||||
}
|
||||
}
|
||||
// re-invalidate all old devices. It's needed because those in the list
|
||||
// may become "invalid" again - if the current default device is removed,
|
||||
// for example. Also, they need to be notified about display
|
||||
// changes as well.
|
||||
if (oldDevices != null) {
|
||||
int defScreen = getDefaultScreen();
|
||||
for (ListIterator<WeakReference<Win32GraphicsDevice>> it =
|
||||
oldDevices.listIterator(); it.hasNext();)
|
||||
{
|
||||
Win32GraphicsDevice gd = it.next().get();
|
||||
if (gd != null) {
|
||||
gd.invalidate(defScreen);
|
||||
gd.displayChanged();
|
||||
} else {
|
||||
// no more references to this device, remove it
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reset the static GC for the (possibly new) default screen
|
||||
WToolkit.resetGC();
|
||||
|
||||
// notify SunDisplayChanger list (e.g. VolatileSurfaceManagers and
|
||||
// CachingSurfaceManagers) about the display change event
|
||||
displayChanger.notifyListeners();
|
||||
// note: do not call super.displayChanged, we've already done everything
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----END DISPLAY CHANGE SUPPORT----
|
||||
*/
|
||||
|
||||
protected GraphicsDevice makeScreenDevice(int screennum) {
|
||||
GraphicsDevice device = null;
|
||||
if (WindowsFlags.isD3DEnabled()) {
|
||||
device = D3DGraphicsDevice.createDevice(screennum);
|
||||
}
|
||||
if (device == null) {
|
||||
device = new Win32GraphicsDevice(screennum);
|
||||
}
|
||||
return device;
|
||||
}
|
||||
|
||||
public boolean isDisplayLocal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlipStrategyPreferred(ComponentPeer peer) {
|
||||
GraphicsConfiguration gc;
|
||||
if (peer != null && (gc = peer.getGraphicsConfiguration()) != null) {
|
||||
GraphicsDevice gd = gc.getDevice();
|
||||
if (gd instanceof D3DGraphicsDevice) {
|
||||
return ((D3DGraphicsDevice)gd).isD3DEnabledOnDevice();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static volatile boolean isDWMCompositionEnabled;
|
||||
/**
|
||||
* Returns true if dwm composition is currently enabled, false otherwise.
|
||||
*
|
||||
* @return true if dwm composition is enabled, false otherwise
|
||||
*/
|
||||
public static boolean isDWMCompositionEnabled() {
|
||||
return isDWMCompositionEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the native code when DWM composition state changed.
|
||||
* May be called multiple times during the lifetime of the application.
|
||||
* REMIND: we may want to create a listener mechanism for this.
|
||||
*
|
||||
* Note: called on the Toolkit thread, no user code or locks are allowed.
|
||||
*
|
||||
* @param enabled indicates the state of dwm composition
|
||||
*/
|
||||
private static void dwmCompositionChanged(boolean enabled) {
|
||||
isDWMCompositionEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to find out if the OS is Windows Vista or later.
|
||||
*
|
||||
* @return {@code true} if the OS is Vista or later, {@code false} otherwise
|
||||
*/
|
||||
public static native boolean isVistaOS();
|
||||
}
|
||||
53
jdkSrc/jdk8/sun/awt/WindowClosingListener.java
Normal file
53
jdkSrc/jdk8/sun/awt/WindowClosingListener.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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;
|
||||
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
/**
|
||||
* Interface for listening to WINDOW_CLOSING events before and
|
||||
* after they are posted to the queue.
|
||||
*/
|
||||
public interface WindowClosingListener {
|
||||
/**
|
||||
* Called before a WINDOW_CLOSING event gets posted to the queue.
|
||||
* @param event The WINDOW_CLOSING event that will be posted.
|
||||
* @return A RuntimeException if the result of this function
|
||||
* call needs to interrupt a blocking thread. The exception
|
||||
* returned will be thrown from that thread. This function
|
||||
* should return null otherwise.
|
||||
*/
|
||||
RuntimeException windowClosingNotify(WindowEvent event);
|
||||
/**
|
||||
* Called after a WINDOW_CLOSING event gets posted to the queue.
|
||||
* @param event The WINDOW_CLOSING event that has been posted.
|
||||
* @return A RuntimeException if the result of this function
|
||||
* call needs to interrupt a blocking thread. The exception
|
||||
* returned will be thrown from that thread. This function
|
||||
* should return null otherwise.
|
||||
*/
|
||||
RuntimeException windowClosingDelivered(WindowEvent event);
|
||||
}
|
||||
35
jdkSrc/jdk8/sun/awt/WindowClosingSupport.java
Normal file
35
jdkSrc/jdk8/sun/awt/WindowClosingSupport.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2007, 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;
|
||||
|
||||
/**
|
||||
* Interface for identifying and casting toolkits that support
|
||||
* WindowClosingListeners.
|
||||
*/
|
||||
public interface WindowClosingSupport {
|
||||
WindowClosingListener getWindowClosingListener();
|
||||
void setWindowClosingListener(WindowClosingListener wcl);
|
||||
}
|
||||
34
jdkSrc/jdk8/sun/awt/WindowIDProvider.java
Normal file
34
jdkSrc/jdk8/sun/awt/WindowIDProvider.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2005, 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;
|
||||
|
||||
/**
|
||||
* Classes implementing this interface have public getWindow method,
|
||||
* returning handle to the native window.
|
||||
*/
|
||||
public interface WindowIDProvider {
|
||||
public long getWindow();
|
||||
}
|
||||
173
jdkSrc/jdk8/sun/awt/datatransfer/ClipboardTransferable.java
Normal file
173
jdkSrc/jdk8/sun/awt/datatransfer/ClipboardTransferable.java
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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.datatransfer;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Reads all of the data from the system Clipboard which the data transfer
|
||||
* subsystem knows how to translate. This includes all text data, File Lists,
|
||||
* Serializable objects, Remote objects, and properly registered, arbitrary
|
||||
* data as InputStreams. The data is stored in byte format until requested
|
||||
* by client code. At that point, the data is converted, if necessary, into
|
||||
* the proper format to deliver to the application.
|
||||
*
|
||||
* This hybrid pre-fetch/delayed-rendering approach allows us to circumvent
|
||||
* the API restriction that client code cannot lock the Clipboard to discover
|
||||
* its formats before requesting data in a particular format, while avoiding
|
||||
* the overhead of fully rendering all data ahead of time.
|
||||
*
|
||||
* @author David Mendenhall
|
||||
* @author Danila Sinopalnikov
|
||||
*
|
||||
* @since 1.4 (appeared in modified form as FullyRenderedTransferable in 1.3.1)
|
||||
*/
|
||||
public class ClipboardTransferable implements Transferable {
|
||||
private final HashMap flavorsToData = new HashMap();
|
||||
private DataFlavor[] flavors = new DataFlavor[0];
|
||||
|
||||
private final class DataFactory {
|
||||
final long format;
|
||||
final byte[] data;
|
||||
DataFactory(long format, byte[] data) {
|
||||
this.format = format;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Object getTransferData(DataFlavor flavor) throws IOException {
|
||||
return DataTransferer.getInstance().
|
||||
translateBytes(data, flavor, format,
|
||||
ClipboardTransferable.this);
|
||||
}
|
||||
}
|
||||
|
||||
public ClipboardTransferable(SunClipboard clipboard) {
|
||||
|
||||
clipboard.openClipboard(null);
|
||||
|
||||
try {
|
||||
long[] formats = clipboard.getClipboardFormats();
|
||||
|
||||
if (formats != null && formats.length > 0) {
|
||||
// Since the SystemFlavorMap will specify many DataFlavors
|
||||
// which map to the same format, we should cache data as we
|
||||
// read it.
|
||||
HashMap cached_data = new HashMap(formats.length, 1.0f);
|
||||
|
||||
Map flavorsForFormats = DataTransferer.getInstance().
|
||||
getFlavorsForFormats(formats, SunClipboard.getDefaultFlavorTable());
|
||||
for (Iterator iter = flavorsForFormats.keySet().iterator();
|
||||
iter.hasNext(); )
|
||||
{
|
||||
DataFlavor flavor = (DataFlavor)iter.next();
|
||||
Long lFormat = (Long)flavorsForFormats.get(flavor);
|
||||
|
||||
fetchOneFlavor(clipboard, flavor, lFormat, cached_data);
|
||||
}
|
||||
|
||||
flavors = DataTransferer.getInstance().
|
||||
setToSortedDataFlavorArray(flavorsToData.keySet());
|
||||
}
|
||||
} finally {
|
||||
clipboard.closeClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean fetchOneFlavor(SunClipboard clipboard, DataFlavor flavor,
|
||||
Long lFormat, HashMap cached_data)
|
||||
{
|
||||
if (!flavorsToData.containsKey(flavor)) {
|
||||
long format = lFormat.longValue();
|
||||
Object data = null;
|
||||
|
||||
if (!cached_data.containsKey(lFormat)) {
|
||||
try {
|
||||
data = clipboard.getClipboardData(format);
|
||||
} catch (IOException e) {
|
||||
data = e;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Cache this data, even if it's null, so we don't have to go
|
||||
// to native code again for this format.
|
||||
cached_data.put(lFormat, data);
|
||||
} else {
|
||||
data = cached_data.get(lFormat);
|
||||
}
|
||||
|
||||
// Casting IOException to byte array causes ClassCastException.
|
||||
// We should handle IOException separately - do not wrap them into
|
||||
// DataFactory and report failure.
|
||||
if (data instanceof IOException) {
|
||||
flavorsToData.put(flavor, data);
|
||||
return false;
|
||||
} else if (data != null) {
|
||||
flavorsToData.put(flavor, new DataFactory(format,
|
||||
(byte[])data));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return (DataFlavor[])flavors.clone();
|
||||
}
|
||||
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
return flavorsToData.containsKey(flavor);
|
||||
}
|
||||
|
||||
public Object getTransferData(DataFlavor flavor)
|
||||
throws UnsupportedFlavorException, IOException
|
||||
{
|
||||
if (!isDataFlavorSupported(flavor)) {
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
}
|
||||
Object ret = flavorsToData.get(flavor);
|
||||
if (ret instanceof IOException) {
|
||||
// rethrow IOExceptions generated while fetching data
|
||||
throw (IOException)ret;
|
||||
} else if (ret instanceof DataFactory) {
|
||||
// Now we can render the data
|
||||
DataFactory factory = (DataFactory)ret;
|
||||
ret = factory.getTransferData(flavor);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
3068
jdkSrc/jdk8/sun/awt/datatransfer/DataTransferer.java
Normal file
3068
jdkSrc/jdk8/sun/awt/datatransfer/DataTransferer.java
Normal file
File diff suppressed because it is too large
Load Diff
468
jdkSrc/jdk8/sun/awt/datatransfer/SunClipboard.java
Normal file
468
jdkSrc/jdk8/sun/awt/datatransfer/SunClipboard.java
Normal file
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, 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.datatransfer;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.FlavorTable;
|
||||
import java.awt.datatransfer.SystemFlavorMap;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.ClipboardOwner;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.FlavorListener;
|
||||
import java.awt.datatransfer.FlavorEvent;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.awt.AppContext;
|
||||
import sun.awt.PeerEvent;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.EventListenerAggregate;
|
||||
|
||||
|
||||
/**
|
||||
* Serves as a common, helper superclass for the Win32 and X11 system
|
||||
* Clipboards.
|
||||
*
|
||||
* @author Danila Sinopalnikov
|
||||
* @author Alexander Gerasimov
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public abstract class SunClipboard extends Clipboard
|
||||
implements PropertyChangeListener {
|
||||
|
||||
private AppContext contentsContext = null;
|
||||
|
||||
private final Object CLIPBOARD_FLAVOR_LISTENER_KEY;
|
||||
|
||||
/**
|
||||
* A number of <code>FlavorListener</code>s currently registered
|
||||
* on this clipboard across all <code>AppContext</code>s.
|
||||
*/
|
||||
private volatile int numberOfFlavorListeners = 0;
|
||||
|
||||
/**
|
||||
* A set of {@code DataFlavor}s that is available on this clipboard. It is
|
||||
* used for tracking changes of {@code DataFlavor}s available on this
|
||||
* clipboard. Can be {@code null}.
|
||||
*/
|
||||
private volatile long[] currentFormats;
|
||||
|
||||
public SunClipboard(String name) {
|
||||
super(name);
|
||||
CLIPBOARD_FLAVOR_LISTENER_KEY = new StringBuffer(name + "_CLIPBOARD_FLAVOR_LISTENER_KEY");
|
||||
}
|
||||
|
||||
public synchronized void setContents(Transferable contents,
|
||||
ClipboardOwner owner) {
|
||||
// 4378007 : Toolkit.getSystemClipboard().setContents(null, null)
|
||||
// should throw NPE
|
||||
if (contents == null) {
|
||||
throw new NullPointerException("contents");
|
||||
}
|
||||
|
||||
initContext();
|
||||
|
||||
final ClipboardOwner oldOwner = this.owner;
|
||||
final Transferable oldContents = this.contents;
|
||||
|
||||
try {
|
||||
this.owner = owner;
|
||||
this.contents = new TransferableProxy(contents, true);
|
||||
|
||||
setContentsNative(contents);
|
||||
} finally {
|
||||
if (oldOwner != null && oldOwner != owner) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
oldOwner.lostOwnership(SunClipboard.this, oldContents);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void initContext() {
|
||||
final AppContext context = AppContext.getAppContext();
|
||||
|
||||
if (contentsContext != context) {
|
||||
// Need to synchronize on the AppContext to guarantee that it cannot
|
||||
// be disposed after the check, but before the listener is added.
|
||||
synchronized (context) {
|
||||
if (context.isDisposed()) {
|
||||
throw new IllegalStateException("Can't set contents from disposed AppContext");
|
||||
}
|
||||
context.addPropertyChangeListener
|
||||
(AppContext.DISPOSED_PROPERTY_NAME, this);
|
||||
}
|
||||
if (contentsContext != null) {
|
||||
contentsContext.removePropertyChangeListener
|
||||
(AppContext.DISPOSED_PROPERTY_NAME, this);
|
||||
}
|
||||
contentsContext = context;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Transferable getContents(Object requestor) {
|
||||
if (contents != null) {
|
||||
return contents;
|
||||
}
|
||||
return new ClipboardTransferable(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the contents of this clipboard if it has been set from the same
|
||||
* AppContext as it is currently retrieved or null otherwise
|
||||
* @since 1.5
|
||||
*/
|
||||
protected synchronized Transferable getContextContents() {
|
||||
AppContext context = AppContext.getAppContext();
|
||||
return (context == contentsContext) ? contents : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see java.awt.Clipboard#getAvailableDataFlavors
|
||||
* @since 1.5
|
||||
*/
|
||||
public DataFlavor[] getAvailableDataFlavors() {
|
||||
Transferable cntnts = getContextContents();
|
||||
if (cntnts != null) {
|
||||
return cntnts.getTransferDataFlavors();
|
||||
}
|
||||
|
||||
long[] formats = getClipboardFormatsOpenClose();
|
||||
|
||||
return DataTransferer.getInstance().
|
||||
getFlavorsForFormatsAsArray(formats, getDefaultFlavorTable());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.Clipboard#isDataFlavorAvailable
|
||||
* @since 1.5
|
||||
*/
|
||||
public boolean isDataFlavorAvailable(DataFlavor flavor) {
|
||||
if (flavor == null) {
|
||||
throw new NullPointerException("flavor");
|
||||
}
|
||||
|
||||
Transferable cntnts = getContextContents();
|
||||
if (cntnts != null) {
|
||||
return cntnts.isDataFlavorSupported(flavor);
|
||||
}
|
||||
|
||||
long[] formats = getClipboardFormatsOpenClose();
|
||||
|
||||
return formatArrayAsDataFlavorSet(formats).contains(flavor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.Clipboard#getData
|
||||
* @since 1.5
|
||||
*/
|
||||
public Object getData(DataFlavor flavor)
|
||||
throws UnsupportedFlavorException, IOException {
|
||||
if (flavor == null) {
|
||||
throw new NullPointerException("flavor");
|
||||
}
|
||||
|
||||
Transferable cntnts = getContextContents();
|
||||
if (cntnts != null) {
|
||||
return cntnts.getTransferData(flavor);
|
||||
}
|
||||
|
||||
long format = 0;
|
||||
byte[] data = null;
|
||||
Transferable localeTransferable = null;
|
||||
|
||||
try {
|
||||
openClipboard(null);
|
||||
|
||||
long[] formats = getClipboardFormats();
|
||||
Long lFormat = (Long)DataTransferer.getInstance().
|
||||
getFlavorsForFormats(formats, getDefaultFlavorTable()).get(flavor);
|
||||
|
||||
if (lFormat == null) {
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
}
|
||||
|
||||
format = lFormat.longValue();
|
||||
data = getClipboardData(format);
|
||||
|
||||
if (DataTransferer.getInstance().isLocaleDependentTextFormat(format)) {
|
||||
localeTransferable = createLocaleTransferable(formats);
|
||||
}
|
||||
|
||||
} finally {
|
||||
closeClipboard();
|
||||
}
|
||||
|
||||
return DataTransferer.getInstance().
|
||||
translateBytes(data, flavor, format, localeTransferable);
|
||||
}
|
||||
|
||||
/**
|
||||
* The clipboard must be opened.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected Transferable createLocaleTransferable(long[] formats) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalStateException if the clipboard has not been opened
|
||||
*/
|
||||
public void openClipboard(SunClipboard newOwner) {}
|
||||
public void closeClipboard() {}
|
||||
|
||||
public abstract long getID();
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (AppContext.DISPOSED_PROPERTY_NAME.equals(evt.getPropertyName()) &&
|
||||
Boolean.TRUE.equals(evt.getNewValue())) {
|
||||
final AppContext disposedContext = (AppContext)evt.getSource();
|
||||
lostOwnershipLater(disposedContext);
|
||||
}
|
||||
}
|
||||
|
||||
protected void lostOwnershipImpl() {
|
||||
lostOwnershipLater(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the clipboard state (contents, owner and contents context) and
|
||||
* notifies the current owner that ownership is lost. Does nothing if the
|
||||
* argument is not <code>null</code> and is not equal to the current
|
||||
* contents context.
|
||||
*
|
||||
* @param disposedContext the AppContext that is disposed or
|
||||
* <code>null</code> if the ownership is lost because another
|
||||
* application acquired ownership.
|
||||
*/
|
||||
protected void lostOwnershipLater(final AppContext disposedContext) {
|
||||
final AppContext context = this.contentsContext;
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
SunToolkit.postEvent(context, new PeerEvent(this, () -> lostOwnershipNow(disposedContext),
|
||||
PeerEvent.PRIORITY_EVENT));
|
||||
}
|
||||
|
||||
protected void lostOwnershipNow(final AppContext disposedContext) {
|
||||
final SunClipboard sunClipboard = SunClipboard.this;
|
||||
ClipboardOwner owner = null;
|
||||
Transferable contents = null;
|
||||
|
||||
synchronized (sunClipboard) {
|
||||
final AppContext context = sunClipboard.contentsContext;
|
||||
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposedContext == null || context == disposedContext) {
|
||||
owner = sunClipboard.owner;
|
||||
contents = sunClipboard.contents;
|
||||
sunClipboard.contentsContext = null;
|
||||
sunClipboard.owner = null;
|
||||
sunClipboard.contents = null;
|
||||
sunClipboard.clearNativeContext();
|
||||
context.removePropertyChangeListener
|
||||
(AppContext.DISPOSED_PROPERTY_NAME, sunClipboard);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (owner != null) {
|
||||
owner.lostOwnership(sunClipboard, contents);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected abstract void clearNativeContext();
|
||||
|
||||
protected abstract void setContentsNative(Transferable contents);
|
||||
|
||||
/**
|
||||
* @since 1.5
|
||||
*/
|
||||
protected long[] getClipboardFormatsOpenClose() {
|
||||
try {
|
||||
openClipboard(null);
|
||||
return getClipboardFormats();
|
||||
} finally {
|
||||
closeClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns zero-length array (not null) if the number of available formats is zero.
|
||||
*
|
||||
* @throws IllegalStateException if formats could not be retrieved
|
||||
*/
|
||||
protected abstract long[] getClipboardFormats();
|
||||
|
||||
protected abstract byte[] getClipboardData(long format) throws IOException;
|
||||
|
||||
|
||||
private static Set formatArrayAsDataFlavorSet(long[] formats) {
|
||||
return (formats == null) ? null :
|
||||
DataTransferer.getInstance().
|
||||
getFlavorsForFormatsAsSet(formats, getDefaultFlavorTable());
|
||||
}
|
||||
|
||||
|
||||
public synchronized void addFlavorListener(FlavorListener listener) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
AppContext appContext = AppContext.getAppContext();
|
||||
EventListenerAggregate contextFlavorListeners = (EventListenerAggregate)
|
||||
appContext.get(CLIPBOARD_FLAVOR_LISTENER_KEY);
|
||||
if (contextFlavorListeners == null) {
|
||||
contextFlavorListeners = new EventListenerAggregate(FlavorListener.class);
|
||||
appContext.put(CLIPBOARD_FLAVOR_LISTENER_KEY, contextFlavorListeners);
|
||||
}
|
||||
contextFlavorListeners.add(listener);
|
||||
|
||||
if (numberOfFlavorListeners++ == 0) {
|
||||
long[] currentFormats = null;
|
||||
try {
|
||||
openClipboard(null);
|
||||
currentFormats = getClipboardFormats();
|
||||
} catch (final IllegalStateException ignored) {
|
||||
} finally {
|
||||
closeClipboard();
|
||||
}
|
||||
this.currentFormats = currentFormats;
|
||||
|
||||
registerClipboardViewerChecked();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeFlavorListener(FlavorListener listener) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
AppContext appContext = AppContext.getAppContext();
|
||||
EventListenerAggregate contextFlavorListeners = (EventListenerAggregate)
|
||||
appContext.get(CLIPBOARD_FLAVOR_LISTENER_KEY);
|
||||
if (contextFlavorListeners == null){
|
||||
//else we throw NullPointerException, but it is forbidden
|
||||
return;
|
||||
}
|
||||
if (contextFlavorListeners.remove(listener) &&
|
||||
--numberOfFlavorListeners == 0) {
|
||||
unregisterClipboardViewerChecked();
|
||||
currentFormats = null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized FlavorListener[] getFlavorListeners() {
|
||||
EventListenerAggregate contextFlavorListeners = (EventListenerAggregate)
|
||||
AppContext.getAppContext().get(CLIPBOARD_FLAVOR_LISTENER_KEY);
|
||||
return contextFlavorListeners == null ? new FlavorListener[0] :
|
||||
(FlavorListener[])contextFlavorListeners.getListenersCopy();
|
||||
}
|
||||
|
||||
public boolean areFlavorListenersRegistered() {
|
||||
return (numberOfFlavorListeners > 0);
|
||||
}
|
||||
|
||||
protected abstract void registerClipboardViewerChecked();
|
||||
|
||||
protected abstract void unregisterClipboardViewerChecked();
|
||||
|
||||
/**
|
||||
* Checks change of the <code>DataFlavor</code>s and, if necessary,
|
||||
* posts notifications on <code>FlavorEvent</code>s to the
|
||||
* AppContexts' EDTs.
|
||||
* The parameter <code>formats</code> is null iff we have just
|
||||
* failed to get formats available on the clipboard.
|
||||
*
|
||||
* @param formats data formats that have just been retrieved from
|
||||
* this clipboard
|
||||
*/
|
||||
protected final void checkChange(final long[] formats) {
|
||||
if (Arrays.equals(formats, currentFormats)) {
|
||||
// we've been able to successfully get available on the clipboard
|
||||
// DataFlavors this and previous time and they are coincident;
|
||||
// don't notify
|
||||
return;
|
||||
}
|
||||
currentFormats = formats;
|
||||
|
||||
|
||||
class SunFlavorChangeNotifier implements Runnable {
|
||||
private final FlavorListener flavorListener;
|
||||
|
||||
SunFlavorChangeNotifier(FlavorListener flavorListener) {
|
||||
this.flavorListener = flavorListener;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if (flavorListener != null) {
|
||||
flavorListener.flavorsChanged(new FlavorEvent(SunClipboard.this));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (Iterator it = AppContext.getAppContexts().iterator(); it.hasNext();) {
|
||||
AppContext appContext = (AppContext)it.next();
|
||||
if (appContext == null || appContext.isDisposed()) {
|
||||
continue;
|
||||
}
|
||||
EventListenerAggregate flavorListeners = (EventListenerAggregate)
|
||||
appContext.get(CLIPBOARD_FLAVOR_LISTENER_KEY);
|
||||
if (flavorListeners != null) {
|
||||
FlavorListener[] flavorListenerArray =
|
||||
(FlavorListener[])flavorListeners.getListenersInternal();
|
||||
for (int i = 0; i < flavorListenerArray.length; i++) {
|
||||
SunToolkit.postEvent(appContext, new PeerEvent(this,
|
||||
new SunFlavorChangeNotifier(flavorListenerArray[i]),
|
||||
PeerEvent.PRIORITY_EVENT));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static FlavorTable getDefaultFlavorTable() {
|
||||
return (FlavorTable) SystemFlavorMap.getDefaultFlavorMap();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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.datatransfer;
|
||||
|
||||
public interface ToolkitThreadBlockedHandler {
|
||||
public void lock();
|
||||
public void unlock();
|
||||
public void enter();
|
||||
public void exit();
|
||||
}
|
||||
218
jdkSrc/jdk8/sun/awt/datatransfer/TransferableProxy.java
Normal file
218
jdkSrc/jdk8/sun/awt/datatransfer/TransferableProxy.java
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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.datatransfer;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamClass;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Proxies for another Transferable so that Serializable objects are never
|
||||
* returned directly by DnD or the Clipboard. Instead, a new instance of the
|
||||
* object is returned.
|
||||
*
|
||||
* @author Lawrence P.G. Cable
|
||||
* @author David Mendenhall
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public class TransferableProxy implements Transferable {
|
||||
public TransferableProxy(Transferable t, boolean local) {
|
||||
transferable = t;
|
||||
isLocal = local;
|
||||
}
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return transferable.getTransferDataFlavors();
|
||||
}
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
return transferable.isDataFlavorSupported(flavor);
|
||||
}
|
||||
public Object getTransferData(DataFlavor df)
|
||||
throws UnsupportedFlavorException, IOException
|
||||
{
|
||||
Object data = transferable.getTransferData(df);
|
||||
|
||||
// If the data is a Serializable object, then create a new instance
|
||||
// before returning it. This insulates applications sharing DnD and
|
||||
// Clipboard data from each other.
|
||||
if (data != null && isLocal && df.isFlavorSerializedObjectType()) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
ClassLoaderObjectOutputStream oos =
|
||||
new ClassLoaderObjectOutputStream(baos);
|
||||
oos.writeObject(data);
|
||||
|
||||
ByteArrayInputStream bais =
|
||||
new ByteArrayInputStream(baos.toByteArray());
|
||||
|
||||
try {
|
||||
ClassLoaderObjectInputStream ois =
|
||||
new ClassLoaderObjectInputStream(bais,
|
||||
oos.getClassLoaderMap());
|
||||
data = ois.readObject();
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
throw (IOException)new IOException().initCause(cnfe);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
protected final Transferable transferable;
|
||||
protected final boolean isLocal;
|
||||
}
|
||||
|
||||
final class ClassLoaderObjectOutputStream extends ObjectOutputStream {
|
||||
private final Map<Set<String>, ClassLoader> map =
|
||||
new HashMap<Set<String>, ClassLoader>();
|
||||
|
||||
ClassLoaderObjectOutputStream(OutputStream os) throws IOException {
|
||||
super(os);
|
||||
}
|
||||
|
||||
protected void annotateClass(final Class<?> cl) throws IOException {
|
||||
ClassLoader classLoader =
|
||||
(ClassLoader)AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
return cl.getClassLoader();
|
||||
}
|
||||
});
|
||||
|
||||
Set<String> s = new HashSet<String>(1);
|
||||
s.add(cl.getName());
|
||||
|
||||
map.put(s, classLoader);
|
||||
}
|
||||
protected void annotateProxyClass(final Class<?> cl) throws IOException {
|
||||
ClassLoader classLoader =
|
||||
(ClassLoader)AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
return cl.getClassLoader();
|
||||
}
|
||||
});
|
||||
|
||||
Class[] interfaces = cl.getInterfaces();
|
||||
Set<String> s = new HashSet<String>(interfaces.length);
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
s.add(interfaces[i].getName());
|
||||
}
|
||||
|
||||
map.put(s, classLoader);
|
||||
}
|
||||
|
||||
Map<Set<String>, ClassLoader> getClassLoaderMap() {
|
||||
return new HashMap(map);
|
||||
}
|
||||
}
|
||||
|
||||
final class ClassLoaderObjectInputStream extends ObjectInputStream {
|
||||
private final Map<Set<String>, ClassLoader> map;
|
||||
|
||||
ClassLoaderObjectInputStream(InputStream is,
|
||||
Map<Set<String>, ClassLoader> map)
|
||||
throws IOException {
|
||||
super(is);
|
||||
if (map == null) {
|
||||
throw new NullPointerException("Null map");
|
||||
}
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
protected Class<?> resolveClass(ObjectStreamClass classDesc)
|
||||
throws IOException, ClassNotFoundException {
|
||||
String className = classDesc.getName();
|
||||
|
||||
Set<String> s = new HashSet<String>(1);
|
||||
s.add(className);
|
||||
|
||||
ClassLoader classLoader = map.get(s);
|
||||
if (classLoader != null) {
|
||||
return Class.forName(className, false, classLoader);
|
||||
} else {
|
||||
return super.resolveClass(classDesc);
|
||||
}
|
||||
}
|
||||
|
||||
protected Class<?> resolveProxyClass(String[] interfaces)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
Set<String> s = new HashSet<String>(interfaces.length);
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
s.add(interfaces[i]);
|
||||
}
|
||||
|
||||
ClassLoader classLoader = map.get(s);
|
||||
if (classLoader == null) {
|
||||
return super.resolveProxyClass(interfaces);
|
||||
}
|
||||
|
||||
// The code below is mostly copied from the superclass.
|
||||
ClassLoader nonPublicLoader = null;
|
||||
boolean hasNonPublicInterface = false;
|
||||
|
||||
// define proxy in class loader of non-public interface(s), if any
|
||||
Class[] classObjs = new Class[interfaces.length];
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
Class cl = Class.forName(interfaces[i], false, classLoader);
|
||||
if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
|
||||
if (hasNonPublicInterface) {
|
||||
if (nonPublicLoader != cl.getClassLoader()) {
|
||||
throw new IllegalAccessError(
|
||||
"conflicting non-public interface class loaders");
|
||||
}
|
||||
} else {
|
||||
nonPublicLoader = cl.getClassLoader();
|
||||
hasNonPublicInterface = true;
|
||||
}
|
||||
}
|
||||
classObjs[i] = cl;
|
||||
}
|
||||
try {
|
||||
return Proxy.getProxyClass(hasNonPublicInterface ?
|
||||
nonPublicLoader : classLoader,
|
||||
classObjs);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ClassNotFoundException(null, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
502
jdkSrc/jdk8/sun/awt/dnd/SunDragSourceContextPeer.java
Normal file
502
jdkSrc/jdk8/sun/awt/dnd/SunDragSourceContextPeer.java
Normal file
@@ -0,0 +1,502 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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.dnd;
|
||||
|
||||
import java.awt.AWTEvent;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
|
||||
import java.awt.datatransfer.Transferable;
|
||||
|
||||
import java.awt.dnd.DnDConstants;
|
||||
import java.awt.dnd.DragSourceContext;
|
||||
import java.awt.dnd.DragSourceEvent;
|
||||
import java.awt.dnd.DragSourceDropEvent;
|
||||
import java.awt.dnd.DragSourceDragEvent;
|
||||
import java.awt.dnd.DragGestureEvent;
|
||||
import java.awt.dnd.InvalidDnDOperationException;
|
||||
|
||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.datatransfer.DataTransferer;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* TBC
|
||||
* </p>
|
||||
*
|
||||
* @since JDK1.3.1
|
||||
*
|
||||
*/
|
||||
public abstract class SunDragSourceContextPeer implements DragSourceContextPeer {
|
||||
|
||||
private DragGestureEvent trigger;
|
||||
private Component component;
|
||||
private Cursor cursor;
|
||||
private Image dragImage;
|
||||
private Point dragImageOffset;
|
||||
private long nativeCtxt;
|
||||
private DragSourceContext dragSourceContext;
|
||||
private int sourceActions;
|
||||
|
||||
private static boolean dragDropInProgress = false;
|
||||
private static boolean discardingMouseEvents = false;
|
||||
|
||||
/*
|
||||
* dispatch constants
|
||||
*/
|
||||
|
||||
protected final static int DISPATCH_ENTER = 1;
|
||||
protected final static int DISPATCH_MOTION = 2;
|
||||
protected final static int DISPATCH_CHANGED = 3;
|
||||
protected final static int DISPATCH_EXIT = 4;
|
||||
protected final static int DISPATCH_FINISH = 5;
|
||||
protected final static int DISPATCH_MOUSE_MOVED = 6;
|
||||
|
||||
/**
|
||||
* construct a new SunDragSourceContextPeer
|
||||
*/
|
||||
|
||||
public SunDragSourceContextPeer(DragGestureEvent dge) {
|
||||
trigger = dge;
|
||||
if (trigger != null) {
|
||||
component = trigger.getComponent();
|
||||
} else {
|
||||
component = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchro messages in AWT
|
||||
*/
|
||||
public void startSecondaryEventLoop(){}
|
||||
public void quitSecondaryEventLoop(){}
|
||||
|
||||
/**
|
||||
* initiate a DnD operation ...
|
||||
*/
|
||||
|
||||
public void startDrag(DragSourceContext dsc, Cursor c, Image di, Point p)
|
||||
throws InvalidDnDOperationException {
|
||||
|
||||
/* Fix for 4354044: don't initiate a drag if event sequence provided by
|
||||
* DragGestureRecognizer is empty */
|
||||
if (getTrigger().getTriggerEvent() == null) {
|
||||
throw new InvalidDnDOperationException("DragGestureEvent has a null trigger");
|
||||
}
|
||||
|
||||
dragSourceContext = dsc;
|
||||
cursor = c;
|
||||
sourceActions = getDragSourceContext().getSourceActions();
|
||||
dragImage = di;
|
||||
dragImageOffset = p;
|
||||
|
||||
Transferable transferable = getDragSourceContext().getTransferable();
|
||||
SortedMap<Long,DataFlavor> formatMap = DataTransferer.getInstance().
|
||||
getFormatsForTransferable(transferable, DataTransferer.adaptFlavorMap
|
||||
(getTrigger().getDragSource().getFlavorMap()));
|
||||
long[] formats = DataTransferer.getInstance().
|
||||
keysToLongArray(formatMap);
|
||||
startDrag(transferable, formats, formatMap);
|
||||
|
||||
/*
|
||||
* Fix for 4613903.
|
||||
* Filter out all mouse events that are currently on the event queue.
|
||||
*/
|
||||
discardingMouseEvents = true;
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
discardingMouseEvents = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract void startDrag(Transferable trans,
|
||||
long[] formats, Map formatMap);
|
||||
|
||||
/**
|
||||
* set cursor
|
||||
*/
|
||||
|
||||
public void setCursor(Cursor c) throws InvalidDnDOperationException {
|
||||
synchronized (this) {
|
||||
if (cursor == null || !cursor.equals(c)) {
|
||||
cursor = c;
|
||||
// NOTE: native context can be null at this point.
|
||||
// setNativeCursor() should handle it properly.
|
||||
setNativeCursor(getNativeContext(), c,
|
||||
c != null ? c.getType() : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return cursor
|
||||
*/
|
||||
|
||||
public Cursor getCursor() {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the drag image. If there is no image to drag,
|
||||
* the returned value is {@code null}
|
||||
*
|
||||
* @return the reference to the drag image
|
||||
*/
|
||||
public Image getDragImage() {
|
||||
return dragImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an anchor offset for the image to drag.
|
||||
*
|
||||
* @return a {@code Point} object that corresponds
|
||||
* to coordinates of an anchor offset of the image
|
||||
* relative to the upper left corner of the image.
|
||||
* The point {@code (0,0)} returns by default.
|
||||
*/
|
||||
public Point getDragImageOffset() {
|
||||
if (dragImageOffset == null) {
|
||||
return new Point(0,0);
|
||||
}
|
||||
return new Point(dragImageOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* downcall into native code
|
||||
*/
|
||||
|
||||
|
||||
protected abstract void setNativeCursor(long nativeCtxt, Cursor c,
|
||||
int cType);
|
||||
|
||||
protected synchronized void setTrigger(DragGestureEvent dge) {
|
||||
trigger = dge;
|
||||
if (trigger != null) {
|
||||
component = trigger.getComponent();
|
||||
} else {
|
||||
component = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected DragGestureEvent getTrigger() {
|
||||
return trigger;
|
||||
}
|
||||
|
||||
protected Component getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
protected synchronized void setNativeContext(long ctxt) {
|
||||
nativeCtxt = ctxt;
|
||||
}
|
||||
|
||||
protected synchronized long getNativeContext() {
|
||||
return nativeCtxt;
|
||||
}
|
||||
|
||||
protected DragSourceContext getDragSourceContext() {
|
||||
return dragSourceContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the peer that the transferables' DataFlavors have changed.
|
||||
*
|
||||
* No longer useful as the transferables are determined at the time
|
||||
* of the drag.
|
||||
*/
|
||||
|
||||
public void transferablesFlavorsChanged() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected final void postDragSourceDragEvent(final int targetAction,
|
||||
final int modifiers,
|
||||
final int x, final int y,
|
||||
final int dispatchType) {
|
||||
|
||||
final int dropAction =
|
||||
SunDragSourceContextPeer.convertModifiersToDropAction(modifiers,
|
||||
sourceActions);
|
||||
|
||||
DragSourceDragEvent event =
|
||||
new DragSourceDragEvent(getDragSourceContext(),
|
||||
dropAction,
|
||||
targetAction & sourceActions,
|
||||
modifiers, x, y);
|
||||
EventDispatcher dispatcher = new EventDispatcher(dispatchType, event);
|
||||
|
||||
SunToolkit.invokeLaterOnAppContext(
|
||||
SunToolkit.targetToAppContext(getComponent()), dispatcher);
|
||||
|
||||
startSecondaryEventLoop();
|
||||
}
|
||||
|
||||
/**
|
||||
* upcall from native code
|
||||
*/
|
||||
|
||||
protected void dragEnter(final int targetActions,
|
||||
final int modifiers,
|
||||
final int x, final int y) {
|
||||
postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* upcall from native code
|
||||
*/
|
||||
|
||||
private void dragMotion(final int targetActions,
|
||||
final int modifiers,
|
||||
final int x, final int y) {
|
||||
postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_MOTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* upcall from native code
|
||||
*/
|
||||
|
||||
private void operationChanged(final int targetActions,
|
||||
final int modifiers,
|
||||
final int x, final int y) {
|
||||
postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_CHANGED);
|
||||
}
|
||||
|
||||
/**
|
||||
* upcall from native code
|
||||
*/
|
||||
|
||||
protected final void dragExit(final int x, final int y) {
|
||||
DragSourceEvent event =
|
||||
new DragSourceEvent(getDragSourceContext(), x, y);
|
||||
EventDispatcher dispatcher =
|
||||
new EventDispatcher(DISPATCH_EXIT, event);
|
||||
|
||||
SunToolkit.invokeLaterOnAppContext(
|
||||
SunToolkit.targetToAppContext(getComponent()), dispatcher);
|
||||
|
||||
startSecondaryEventLoop();
|
||||
}
|
||||
|
||||
/**
|
||||
* upcall from native code
|
||||
*/
|
||||
|
||||
private void dragMouseMoved(final int targetActions,
|
||||
final int modifiers,
|
||||
final int x, final int y) {
|
||||
postDragSourceDragEvent(targetActions, modifiers, x, y,
|
||||
DISPATCH_MOUSE_MOVED);
|
||||
}
|
||||
|
||||
/**
|
||||
* upcall from native code via implemented class (do)
|
||||
*/
|
||||
|
||||
protected final void dragDropFinished(final boolean success,
|
||||
final int operations,
|
||||
final int x, final int y) {
|
||||
DragSourceEvent event =
|
||||
new DragSourceDropEvent(getDragSourceContext(),
|
||||
operations & sourceActions,
|
||||
success, x, y);
|
||||
EventDispatcher dispatcher =
|
||||
new EventDispatcher(DISPATCH_FINISH, event);
|
||||
|
||||
SunToolkit.invokeLaterOnAppContext(
|
||||
SunToolkit.targetToAppContext(getComponent()), dispatcher);
|
||||
|
||||
startSecondaryEventLoop();
|
||||
setNativeContext(0);
|
||||
dragImage = null;
|
||||
dragImageOffset = null;
|
||||
}
|
||||
|
||||
public static void setDragDropInProgress(boolean b)
|
||||
throws InvalidDnDOperationException {
|
||||
synchronized (SunDragSourceContextPeer.class) {
|
||||
if (dragDropInProgress == b) {
|
||||
throw new InvalidDnDOperationException(getExceptionMessage(b));
|
||||
}
|
||||
dragDropInProgress = b;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out all mouse events that were on the java event queue when
|
||||
* startDrag was called.
|
||||
*/
|
||||
public static boolean checkEvent(AWTEvent event) {
|
||||
if (discardingMouseEvents && event instanceof MouseEvent) {
|
||||
MouseEvent mouseEvent = (MouseEvent)event;
|
||||
if (!(mouseEvent instanceof SunDropTargetEvent)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void checkDragDropInProgress()
|
||||
throws InvalidDnDOperationException {
|
||||
if (dragDropInProgress) {
|
||||
throw new InvalidDnDOperationException(getExceptionMessage(true));
|
||||
}
|
||||
}
|
||||
|
||||
private static String getExceptionMessage(boolean b) {
|
||||
return b ? "Drag and drop in progress" : "No drag in progress";
|
||||
}
|
||||
|
||||
public static int convertModifiersToDropAction(final int modifiers,
|
||||
final int supportedActions) {
|
||||
int dropAction = DnDConstants.ACTION_NONE;
|
||||
|
||||
/*
|
||||
* Fix for 4285634.
|
||||
* Calculate the drop action to match Motif DnD behavior.
|
||||
* If the user selects an operation (by pressing a modifier key),
|
||||
* return the selected operation or ACTION_NONE if the selected
|
||||
* operation is not supported by the drag source.
|
||||
* If the user doesn't select an operation search the set of operations
|
||||
* supported by the drag source for ACTION_MOVE, then for
|
||||
* ACTION_COPY, then for ACTION_LINK and return the first operation
|
||||
* found.
|
||||
*/
|
||||
switch (modifiers & (InputEvent.SHIFT_DOWN_MASK |
|
||||
InputEvent.CTRL_DOWN_MASK)) {
|
||||
case InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK:
|
||||
dropAction = DnDConstants.ACTION_LINK; break;
|
||||
case InputEvent.CTRL_DOWN_MASK:
|
||||
dropAction = DnDConstants.ACTION_COPY; break;
|
||||
case InputEvent.SHIFT_DOWN_MASK:
|
||||
dropAction = DnDConstants.ACTION_MOVE; break;
|
||||
default:
|
||||
if ((supportedActions & DnDConstants.ACTION_MOVE) != 0) {
|
||||
dropAction = DnDConstants.ACTION_MOVE;
|
||||
} else if ((supportedActions & DnDConstants.ACTION_COPY) != 0) {
|
||||
dropAction = DnDConstants.ACTION_COPY;
|
||||
} else if ((supportedActions & DnDConstants.ACTION_LINK) != 0) {
|
||||
dropAction = DnDConstants.ACTION_LINK;
|
||||
}
|
||||
}
|
||||
|
||||
return dropAction & supportedActions;
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
trigger = null;
|
||||
component = null;
|
||||
cursor = null;
|
||||
dragSourceContext = null;
|
||||
SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(null);
|
||||
SunDragSourceContextPeer.setDragDropInProgress(false);
|
||||
}
|
||||
|
||||
private class EventDispatcher implements Runnable {
|
||||
|
||||
private final int dispatchType;
|
||||
|
||||
private final DragSourceEvent event;
|
||||
|
||||
EventDispatcher(int dispatchType, DragSourceEvent event) {
|
||||
switch (dispatchType) {
|
||||
case DISPATCH_ENTER:
|
||||
case DISPATCH_MOTION:
|
||||
case DISPATCH_CHANGED:
|
||||
case DISPATCH_MOUSE_MOVED:
|
||||
if (!(event instanceof DragSourceDragEvent)) {
|
||||
throw new IllegalArgumentException("Event: " + event);
|
||||
}
|
||||
break;
|
||||
case DISPATCH_EXIT:
|
||||
break;
|
||||
case DISPATCH_FINISH:
|
||||
if (!(event instanceof DragSourceDropEvent)) {
|
||||
throw new IllegalArgumentException("Event: " + event);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Dispatch type: " +
|
||||
dispatchType);
|
||||
}
|
||||
|
||||
this.dispatchType = dispatchType;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
DragSourceContext dragSourceContext =
|
||||
SunDragSourceContextPeer.this.getDragSourceContext();
|
||||
try {
|
||||
switch (dispatchType) {
|
||||
case DISPATCH_ENTER:
|
||||
dragSourceContext.dragEnter((DragSourceDragEvent)event);
|
||||
break;
|
||||
case DISPATCH_MOTION:
|
||||
dragSourceContext.dragOver((DragSourceDragEvent)event);
|
||||
break;
|
||||
case DISPATCH_CHANGED:
|
||||
dragSourceContext.dropActionChanged((DragSourceDragEvent)event);
|
||||
break;
|
||||
case DISPATCH_EXIT:
|
||||
dragSourceContext.dragExit(event);
|
||||
break;
|
||||
case DISPATCH_MOUSE_MOVED:
|
||||
dragSourceContext.dragMouseMoved((DragSourceDragEvent)event);
|
||||
break;
|
||||
case DISPATCH_FINISH:
|
||||
try {
|
||||
dragSourceContext.dragDropEnd((DragSourceDropEvent)event);
|
||||
} finally {
|
||||
SunDragSourceContextPeer.this.cleanup();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Dispatch type: " +
|
||||
dispatchType);
|
||||
}
|
||||
} finally {
|
||||
SunDragSourceContextPeer.this.quitSecondaryEventLoop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
925
jdkSrc/jdk8/sun/awt/dnd/SunDropTargetContextPeer.java
Normal file
925
jdkSrc/jdk8/sun/awt/dnd/SunDropTargetContextPeer.java
Normal file
@@ -0,0 +1,925 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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.dnd;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Point;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
|
||||
import java.awt.dnd.DnDConstants;
|
||||
|
||||
import java.awt.dnd.DropTarget;
|
||||
import java.awt.dnd.DropTargetContext;
|
||||
import java.awt.dnd.DropTargetListener;
|
||||
import java.awt.dnd.DropTargetEvent;
|
||||
import java.awt.dnd.DropTargetDragEvent;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
import java.awt.dnd.InvalidDnDOperationException;
|
||||
|
||||
import java.awt.dnd.peer.DropTargetContextPeer;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import sun.awt.AppContext;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.datatransfer.DataTransferer;
|
||||
import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The SunDropTargetContextPeer class is the generic class responsible for handling
|
||||
* the interaction between a windowing systems DnD system and Java.
|
||||
* </p>
|
||||
*
|
||||
* @since JDK1.3.1
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class SunDropTargetContextPeer implements DropTargetContextPeer, Transferable {
|
||||
|
||||
/*
|
||||
* A boolean constant that requires the peer to wait until the
|
||||
* SunDropTargetEvent is processed and return the status back
|
||||
* to the native code.
|
||||
*/
|
||||
public static final boolean DISPATCH_SYNC = true;
|
||||
private DropTarget currentDT;
|
||||
private DropTargetContext currentDTC;
|
||||
private long[] currentT;
|
||||
private int currentA; // target actions
|
||||
private int currentSA; // source actions
|
||||
private int currentDA; // current drop action
|
||||
private int previousDA;
|
||||
|
||||
private long nativeDragContext;
|
||||
|
||||
private Transferable local;
|
||||
|
||||
private boolean dragRejected = false;
|
||||
|
||||
protected int dropStatus = STATUS_NONE;
|
||||
protected boolean dropComplete = false;
|
||||
|
||||
// The flag is used to monitor whether the drop action is
|
||||
// handled by a user. That allows to distinct during
|
||||
// which operation getTransferData() method is invoked.
|
||||
boolean dropInProcess = false;
|
||||
|
||||
/*
|
||||
* global lock
|
||||
*/
|
||||
|
||||
protected static final Object _globalLock = new Object();
|
||||
|
||||
private static final PlatformLogger dndLog = PlatformLogger.getLogger("sun.awt.dnd.SunDropTargetContextPeer");
|
||||
|
||||
/*
|
||||
* a primitive mechanism for advertising intra-JVM Transferables
|
||||
*/
|
||||
|
||||
protected static Transferable currentJVMLocalSourceTransferable = null;
|
||||
|
||||
public static void setCurrentJVMLocalSourceTransferable(Transferable t) throws InvalidDnDOperationException {
|
||||
synchronized(_globalLock) {
|
||||
if (t != null && currentJVMLocalSourceTransferable != null) {
|
||||
throw new InvalidDnDOperationException();
|
||||
} else {
|
||||
currentJVMLocalSourceTransferable = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the transferable iff the operation is in the same VM
|
||||
*/
|
||||
|
||||
private static Transferable getJVMLocalSourceTransferable() {
|
||||
return currentJVMLocalSourceTransferable;
|
||||
}
|
||||
|
||||
/*
|
||||
* constants used by dropAccept() or dropReject()
|
||||
*/
|
||||
|
||||
protected final static int STATUS_NONE = 0; // none pending
|
||||
protected final static int STATUS_WAIT = 1; // drop pending
|
||||
protected final static int STATUS_ACCEPT = 2;
|
||||
protected final static int STATUS_REJECT = -1;
|
||||
|
||||
/**
|
||||
* create the peer
|
||||
*/
|
||||
|
||||
public SunDropTargetContextPeer() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the DropTarget associated with this peer
|
||||
*/
|
||||
|
||||
public DropTarget getDropTarget() { return currentDT; }
|
||||
|
||||
/**
|
||||
* @param actions set the current actions
|
||||
*/
|
||||
|
||||
public synchronized void setTargetActions(int actions) {
|
||||
currentA = actions &
|
||||
(DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current target actions
|
||||
*/
|
||||
|
||||
public int getTargetActions() {
|
||||
return currentA;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the Transferable associated with the drop
|
||||
*/
|
||||
|
||||
public Transferable getTransferable() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current DataFlavors available
|
||||
*/
|
||||
// NOTE: This method may be called by privileged threads.
|
||||
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
final Transferable localTransferable = local;
|
||||
|
||||
if (localTransferable != null) {
|
||||
return localTransferable.getTransferDataFlavors();
|
||||
} else {
|
||||
return DataTransferer.getInstance().getFlavorsForFormatsAsArray
|
||||
(currentT, DataTransferer.adaptFlavorMap
|
||||
(currentDT.getFlavorMap()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if the flavor is supported
|
||||
*/
|
||||
|
||||
public boolean isDataFlavorSupported(DataFlavor df) {
|
||||
Transferable localTransferable = local;
|
||||
|
||||
if (localTransferable != null) {
|
||||
return localTransferable.isDataFlavorSupported(df);
|
||||
} else {
|
||||
return DataTransferer.getInstance().getFlavorsForFormats
|
||||
(currentT, DataTransferer.adaptFlavorMap
|
||||
(currentDT.getFlavorMap())).
|
||||
containsKey(df);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the data
|
||||
*/
|
||||
|
||||
public Object getTransferData(DataFlavor df)
|
||||
throws UnsupportedFlavorException, IOException,
|
||||
InvalidDnDOperationException
|
||||
{
|
||||
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
try {
|
||||
if (!dropInProcess && sm != null) {
|
||||
sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Thread currentThread = Thread.currentThread();
|
||||
currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e);
|
||||
return null;
|
||||
}
|
||||
|
||||
Long lFormat = null;
|
||||
Transferable localTransferable = local;
|
||||
|
||||
if (localTransferable != null) {
|
||||
return localTransferable.getTransferData(df);
|
||||
}
|
||||
|
||||
if (dropStatus != STATUS_ACCEPT || dropComplete) {
|
||||
throw new InvalidDnDOperationException("No drop current");
|
||||
}
|
||||
|
||||
Map flavorMap = DataTransferer.getInstance().getFlavorsForFormats
|
||||
(currentT, DataTransferer.adaptFlavorMap
|
||||
(currentDT.getFlavorMap()));
|
||||
|
||||
lFormat = (Long)flavorMap.get(df);
|
||||
if (lFormat == null) {
|
||||
throw new UnsupportedFlavorException(df);
|
||||
}
|
||||
|
||||
if (df.isRepresentationClassRemote() &&
|
||||
currentDA != DnDConstants.ACTION_LINK) {
|
||||
throw new InvalidDnDOperationException("only ACTION_LINK is permissable for transfer of java.rmi.Remote objects");
|
||||
}
|
||||
|
||||
final long format = lFormat.longValue();
|
||||
|
||||
Object ret = getNativeData(format);
|
||||
|
||||
if (ret instanceof byte[]) {
|
||||
try {
|
||||
return DataTransferer.getInstance().
|
||||
translateBytes((byte[])ret, df, format, this);
|
||||
} catch (IOException e) {
|
||||
throw new InvalidDnDOperationException(e.getMessage());
|
||||
}
|
||||
} else if (ret instanceof InputStream) {
|
||||
try {
|
||||
return DataTransferer.getInstance().
|
||||
translateStream((InputStream)ret, df, format, this);
|
||||
} catch (IOException e) {
|
||||
throw new InvalidDnDOperationException(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
throw new IOException("no native data was transfered");
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Object getNativeData(long format)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* @return if the transfer is a local one
|
||||
*/
|
||||
public boolean isTransferableJVMLocal() {
|
||||
return local != null || getJVMLocalSourceTransferable() != null;
|
||||
}
|
||||
|
||||
private int handleEnterMessage(final Component component,
|
||||
final int x, final int y,
|
||||
final int dropAction,
|
||||
final int actions, final long[] formats,
|
||||
final long nativeCtxt) {
|
||||
return postDropTargetEvent(component, x, y, dropAction, actions,
|
||||
formats, nativeCtxt,
|
||||
SunDropTargetEvent.MOUSE_ENTERED,
|
||||
SunDropTargetContextPeer.DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
/**
|
||||
* actual processing on EventQueue Thread
|
||||
*/
|
||||
|
||||
protected void processEnterMessage(SunDropTargetEvent event) {
|
||||
Component c = (Component)event.getSource();
|
||||
DropTarget dt = c.getDropTarget();
|
||||
Point hots = event.getPoint();
|
||||
|
||||
local = getJVMLocalSourceTransferable();
|
||||
|
||||
if (currentDTC != null) { // some wreckage from last time
|
||||
currentDTC.removeNotify();
|
||||
currentDTC = null;
|
||||
}
|
||||
|
||||
if (c.isShowing() && dt != null && dt.isActive()) {
|
||||
currentDT = dt;
|
||||
currentDTC = currentDT.getDropTargetContext();
|
||||
|
||||
currentDTC.addNotify(this);
|
||||
|
||||
currentA = dt.getDefaultActions();
|
||||
|
||||
try {
|
||||
((DropTargetListener)dt).dragEnter(new DropTargetDragEvent(currentDTC,
|
||||
hots,
|
||||
currentDA,
|
||||
currentSA));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
currentDA = DnDConstants.ACTION_NONE;
|
||||
}
|
||||
} else {
|
||||
currentDT = null;
|
||||
currentDTC = null;
|
||||
currentDA = DnDConstants.ACTION_NONE;
|
||||
currentSA = DnDConstants.ACTION_NONE;
|
||||
currentA = DnDConstants.ACTION_NONE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* upcall to handle exit messages
|
||||
*/
|
||||
|
||||
private void handleExitMessage(final Component component,
|
||||
final long nativeCtxt) {
|
||||
/*
|
||||
* Even though the return value is irrelevant for this event, it is
|
||||
* dispatched synchronously to fix 4393148 properly.
|
||||
*/
|
||||
postDropTargetEvent(component, 0, 0, DnDConstants.ACTION_NONE,
|
||||
DnDConstants.ACTION_NONE, null, nativeCtxt,
|
||||
SunDropTargetEvent.MOUSE_EXITED,
|
||||
SunDropTargetContextPeer.DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
protected void processExitMessage(SunDropTargetEvent event) {
|
||||
Component c = (Component)event.getSource();
|
||||
DropTarget dt = c.getDropTarget();
|
||||
DropTargetContext dtc = null;
|
||||
|
||||
if (dt == null) {
|
||||
currentDT = null;
|
||||
currentT = null;
|
||||
|
||||
if (currentDTC != null) {
|
||||
currentDTC.removeNotify();
|
||||
}
|
||||
|
||||
currentDTC = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (dt != currentDT) {
|
||||
|
||||
if (currentDTC != null) {
|
||||
currentDTC.removeNotify();
|
||||
}
|
||||
|
||||
currentDT = dt;
|
||||
currentDTC = dt.getDropTargetContext();
|
||||
|
||||
currentDTC.addNotify(this);
|
||||
}
|
||||
|
||||
dtc = currentDTC;
|
||||
|
||||
if (dt.isActive()) try {
|
||||
((DropTargetListener)dt).dragExit(new DropTargetEvent(dtc));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
currentA = DnDConstants.ACTION_NONE;
|
||||
currentSA = DnDConstants.ACTION_NONE;
|
||||
currentDA = DnDConstants.ACTION_NONE;
|
||||
currentDT = null;
|
||||
currentT = null;
|
||||
|
||||
currentDTC.removeNotify();
|
||||
currentDTC = null;
|
||||
|
||||
local = null;
|
||||
|
||||
dragRejected = false;
|
||||
}
|
||||
}
|
||||
|
||||
private int handleMotionMessage(final Component component,
|
||||
final int x, final int y,
|
||||
final int dropAction,
|
||||
final int actions, final long[] formats,
|
||||
final long nativeCtxt) {
|
||||
return postDropTargetEvent(component, x, y, dropAction, actions,
|
||||
formats, nativeCtxt,
|
||||
SunDropTargetEvent.MOUSE_DRAGGED,
|
||||
SunDropTargetContextPeer.DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
protected void processMotionMessage(SunDropTargetEvent event,
|
||||
boolean operationChanged) {
|
||||
Component c = (Component)event.getSource();
|
||||
Point hots = event.getPoint();
|
||||
int id = event.getID();
|
||||
DropTarget dt = c.getDropTarget();
|
||||
DropTargetContext dtc = null;
|
||||
|
||||
if (c.isShowing() && (dt != null) && dt.isActive()) {
|
||||
if (currentDT != dt) {
|
||||
if (currentDTC != null) {
|
||||
currentDTC.removeNotify();
|
||||
}
|
||||
|
||||
currentDT = dt;
|
||||
currentDTC = null;
|
||||
}
|
||||
|
||||
dtc = currentDT.getDropTargetContext();
|
||||
if (dtc != currentDTC) {
|
||||
if (currentDTC != null) {
|
||||
currentDTC.removeNotify();
|
||||
}
|
||||
|
||||
currentDTC = dtc;
|
||||
currentDTC.addNotify(this);
|
||||
}
|
||||
|
||||
currentA = currentDT.getDefaultActions();
|
||||
|
||||
try {
|
||||
DropTargetDragEvent dtde = new DropTargetDragEvent(dtc,
|
||||
hots,
|
||||
currentDA,
|
||||
currentSA);
|
||||
DropTargetListener dtl = (DropTargetListener)dt;
|
||||
if (operationChanged) {
|
||||
dtl.dropActionChanged(dtde);
|
||||
} else {
|
||||
dtl.dragOver(dtde);
|
||||
}
|
||||
|
||||
if (dragRejected) {
|
||||
currentDA = DnDConstants.ACTION_NONE;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
currentDA = DnDConstants.ACTION_NONE;
|
||||
}
|
||||
} else {
|
||||
currentDA = DnDConstants.ACTION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* upcall to handle the Drop message
|
||||
*/
|
||||
|
||||
private void handleDropMessage(final Component component,
|
||||
final int x, final int y,
|
||||
final int dropAction, final int actions,
|
||||
final long[] formats,
|
||||
final long nativeCtxt) {
|
||||
postDropTargetEvent(component, x, y, dropAction, actions,
|
||||
formats, nativeCtxt,
|
||||
SunDropTargetEvent.MOUSE_DROPPED,
|
||||
!SunDropTargetContextPeer.DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
protected void processDropMessage(SunDropTargetEvent event) {
|
||||
Component c = (Component)event.getSource();
|
||||
Point hots = event.getPoint();
|
||||
DropTarget dt = c.getDropTarget();
|
||||
|
||||
dropStatus = STATUS_WAIT; // drop pending ACK
|
||||
dropComplete = false;
|
||||
|
||||
if (c.isShowing() && dt != null && dt.isActive()) {
|
||||
DropTargetContext dtc = dt.getDropTargetContext();
|
||||
|
||||
currentDT = dt;
|
||||
|
||||
if (currentDTC != null) {
|
||||
currentDTC.removeNotify();
|
||||
}
|
||||
|
||||
currentDTC = dtc;
|
||||
currentDTC.addNotify(this);
|
||||
currentA = dt.getDefaultActions();
|
||||
|
||||
synchronized(_globalLock) {
|
||||
if ((local = getJVMLocalSourceTransferable()) != null)
|
||||
setCurrentJVMLocalSourceTransferable(null);
|
||||
}
|
||||
|
||||
dropInProcess = true;
|
||||
|
||||
try {
|
||||
((DropTargetListener)dt).drop(new DropTargetDropEvent(dtc,
|
||||
hots,
|
||||
currentDA,
|
||||
currentSA,
|
||||
local != null));
|
||||
} finally {
|
||||
if (dropStatus == STATUS_WAIT) {
|
||||
rejectDrop();
|
||||
} else if (dropComplete == false) {
|
||||
dropComplete(false);
|
||||
}
|
||||
dropInProcess = false;
|
||||
}
|
||||
} else {
|
||||
rejectDrop();
|
||||
}
|
||||
}
|
||||
|
||||
protected int postDropTargetEvent(final Component component,
|
||||
final int x, final int y,
|
||||
final int dropAction,
|
||||
final int actions,
|
||||
final long[] formats,
|
||||
final long nativeCtxt,
|
||||
final int eventID,
|
||||
final boolean dispatchType) {
|
||||
AppContext appContext = SunToolkit.targetToAppContext(component);
|
||||
|
||||
EventDispatcher dispatcher =
|
||||
new EventDispatcher(this, dropAction, actions, formats, nativeCtxt,
|
||||
dispatchType);
|
||||
|
||||
SunDropTargetEvent event =
|
||||
new SunDropTargetEvent(component, eventID, x, y, dispatcher);
|
||||
|
||||
if (dispatchType == SunDropTargetContextPeer.DISPATCH_SYNC) {
|
||||
DataTransferer.getInstance().getToolkitThreadBlockedHandler().lock();
|
||||
}
|
||||
|
||||
// schedule callback
|
||||
SunToolkit.postEvent(appContext, event);
|
||||
|
||||
eventPosted(event);
|
||||
|
||||
if (dispatchType == SunDropTargetContextPeer.DISPATCH_SYNC) {
|
||||
while (!dispatcher.isDone()) {
|
||||
DataTransferer.getInstance().getToolkitThreadBlockedHandler().enter();
|
||||
}
|
||||
|
||||
DataTransferer.getInstance().getToolkitThreadBlockedHandler().unlock();
|
||||
|
||||
// return target's response
|
||||
return dispatcher.getReturnValue();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* acceptDrag
|
||||
*/
|
||||
|
||||
public synchronized void acceptDrag(int dragOperation) {
|
||||
if (currentDT == null) {
|
||||
throw new InvalidDnDOperationException("No Drag pending");
|
||||
}
|
||||
currentDA = mapOperation(dragOperation);
|
||||
if (currentDA != DnDConstants.ACTION_NONE) {
|
||||
dragRejected = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rejectDrag
|
||||
*/
|
||||
|
||||
public synchronized void rejectDrag() {
|
||||
if (currentDT == null) {
|
||||
throw new InvalidDnDOperationException("No Drag pending");
|
||||
}
|
||||
currentDA = DnDConstants.ACTION_NONE;
|
||||
dragRejected = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* acceptDrop
|
||||
*/
|
||||
|
||||
public synchronized void acceptDrop(int dropOperation) {
|
||||
if (dropOperation == DnDConstants.ACTION_NONE)
|
||||
throw new IllegalArgumentException("invalid acceptDrop() action");
|
||||
|
||||
if (dropStatus == STATUS_WAIT || dropStatus == STATUS_ACCEPT) {
|
||||
currentDA = currentA = mapOperation(dropOperation & currentSA);
|
||||
|
||||
dropStatus = STATUS_ACCEPT;
|
||||
dropComplete = false;
|
||||
} else {
|
||||
throw new InvalidDnDOperationException("invalid acceptDrop()");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reject Drop
|
||||
*/
|
||||
|
||||
public synchronized void rejectDrop() {
|
||||
if (dropStatus != STATUS_WAIT) {
|
||||
throw new InvalidDnDOperationException("invalid rejectDrop()");
|
||||
}
|
||||
dropStatus = STATUS_REJECT;
|
||||
/*
|
||||
* Fix for 4285634.
|
||||
* The target rejected the drop means that it doesn't perform any
|
||||
* drop action. This change is to make Solaris behavior consistent
|
||||
* with Win32.
|
||||
*/
|
||||
currentDA = DnDConstants.ACTION_NONE;
|
||||
dropComplete(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* mapOperation
|
||||
*/
|
||||
|
||||
private int mapOperation(int operation) {
|
||||
int[] operations = {
|
||||
DnDConstants.ACTION_MOVE,
|
||||
DnDConstants.ACTION_COPY,
|
||||
DnDConstants.ACTION_LINK,
|
||||
};
|
||||
int ret = DnDConstants.ACTION_NONE;
|
||||
|
||||
for (int i = 0; i < operations.length; i++) {
|
||||
if ((operation & operations[i]) == operations[i]) {
|
||||
ret = operations[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* signal drop complete
|
||||
*/
|
||||
|
||||
public synchronized void dropComplete(boolean success) {
|
||||
if (dropStatus == STATUS_NONE) {
|
||||
throw new InvalidDnDOperationException("No Drop pending");
|
||||
}
|
||||
|
||||
if (currentDTC != null) currentDTC.removeNotify();
|
||||
|
||||
currentDT = null;
|
||||
currentDTC = null;
|
||||
currentT = null;
|
||||
currentA = DnDConstants.ACTION_NONE;
|
||||
|
||||
synchronized(_globalLock) {
|
||||
currentJVMLocalSourceTransferable = null;
|
||||
}
|
||||
|
||||
dropStatus = STATUS_NONE;
|
||||
dropComplete = true;
|
||||
|
||||
try {
|
||||
doDropDone(success, currentDA, local != null);
|
||||
} finally {
|
||||
currentDA = DnDConstants.ACTION_NONE;
|
||||
// The native context is invalid after the drop is done.
|
||||
// Clear the reference to prohibit access.
|
||||
nativeDragContext = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void doDropDone(boolean success,
|
||||
int dropAction, boolean isLocal);
|
||||
|
||||
protected synchronized long getNativeDragContext() {
|
||||
return nativeDragContext;
|
||||
}
|
||||
|
||||
protected void eventPosted(SunDropTargetEvent e) {}
|
||||
|
||||
protected void eventProcessed(SunDropTargetEvent e, int returnValue,
|
||||
boolean dispatcherDone) {}
|
||||
|
||||
protected static class EventDispatcher {
|
||||
|
||||
private final SunDropTargetContextPeer peer;
|
||||
|
||||
// context fields
|
||||
private final int dropAction;
|
||||
private final int actions;
|
||||
private final long[] formats;
|
||||
private long nativeCtxt;
|
||||
private final boolean dispatchType;
|
||||
private boolean dispatcherDone = false;
|
||||
|
||||
// dispatcher state fields
|
||||
private int returnValue = 0;
|
||||
// set of events to be dispatched by this dispatcher
|
||||
private final HashSet eventSet = new HashSet(3);
|
||||
|
||||
static final ToolkitThreadBlockedHandler handler =
|
||||
DataTransferer.getInstance().getToolkitThreadBlockedHandler();
|
||||
|
||||
EventDispatcher(SunDropTargetContextPeer peer,
|
||||
int dropAction,
|
||||
int actions,
|
||||
long[] formats,
|
||||
long nativeCtxt,
|
||||
boolean dispatchType) {
|
||||
|
||||
this.peer = peer;
|
||||
this.nativeCtxt = nativeCtxt;
|
||||
this.dropAction = dropAction;
|
||||
this.actions = actions;
|
||||
this.formats =
|
||||
(null == formats) ? null : Arrays.copyOf(formats, formats.length);
|
||||
this.dispatchType = dispatchType;
|
||||
}
|
||||
|
||||
void dispatchEvent(SunDropTargetEvent e) {
|
||||
int id = e.getID();
|
||||
|
||||
switch (id) {
|
||||
case SunDropTargetEvent.MOUSE_ENTERED:
|
||||
dispatchEnterEvent(e);
|
||||
break;
|
||||
case SunDropTargetEvent.MOUSE_DRAGGED:
|
||||
dispatchMotionEvent(e);
|
||||
break;
|
||||
case SunDropTargetEvent.MOUSE_EXITED:
|
||||
dispatchExitEvent(e);
|
||||
break;
|
||||
case SunDropTargetEvent.MOUSE_DROPPED:
|
||||
dispatchDropEvent(e);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidDnDOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchEnterEvent(SunDropTargetEvent e) {
|
||||
synchronized (peer) {
|
||||
|
||||
// store the drop action here to track operation changes
|
||||
peer.previousDA = dropAction;
|
||||
|
||||
// setup peer context
|
||||
peer.nativeDragContext = nativeCtxt;
|
||||
peer.currentT = formats;
|
||||
peer.currentSA = actions;
|
||||
peer.currentDA = dropAction;
|
||||
// To allow data retrieval.
|
||||
peer.dropStatus = STATUS_ACCEPT;
|
||||
peer.dropComplete = false;
|
||||
|
||||
try {
|
||||
peer.processEnterMessage(e);
|
||||
} finally {
|
||||
peer.dropStatus = STATUS_NONE;
|
||||
}
|
||||
|
||||
setReturnValue(peer.currentDA);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchMotionEvent(SunDropTargetEvent e) {
|
||||
synchronized (peer) {
|
||||
|
||||
boolean operationChanged = peer.previousDA != dropAction;
|
||||
peer.previousDA = dropAction;
|
||||
|
||||
// setup peer context
|
||||
peer.nativeDragContext = nativeCtxt;
|
||||
peer.currentT = formats;
|
||||
peer.currentSA = actions;
|
||||
peer.currentDA = dropAction;
|
||||
// To allow data retrieval.
|
||||
peer.dropStatus = STATUS_ACCEPT;
|
||||
peer.dropComplete = false;
|
||||
|
||||
try {
|
||||
peer.processMotionMessage(e, operationChanged);
|
||||
} finally {
|
||||
peer.dropStatus = STATUS_NONE;
|
||||
}
|
||||
|
||||
setReturnValue(peer.currentDA);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchExitEvent(SunDropTargetEvent e) {
|
||||
synchronized (peer) {
|
||||
|
||||
// setup peer context
|
||||
peer.nativeDragContext = nativeCtxt;
|
||||
|
||||
peer.processExitMessage(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchDropEvent(SunDropTargetEvent e) {
|
||||
synchronized (peer) {
|
||||
|
||||
// setup peer context
|
||||
peer.nativeDragContext = nativeCtxt;
|
||||
peer.currentT = formats;
|
||||
peer.currentSA = actions;
|
||||
peer.currentDA = dropAction;
|
||||
|
||||
peer.processDropMessage(e);
|
||||
}
|
||||
}
|
||||
|
||||
void setReturnValue(int ret) {
|
||||
returnValue = ret;
|
||||
}
|
||||
|
||||
int getReturnValue() {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
boolean isDone() {
|
||||
return eventSet.isEmpty();
|
||||
}
|
||||
|
||||
void registerEvent(SunDropTargetEvent e) {
|
||||
handler.lock();
|
||||
if (!eventSet.add(e) && dndLog.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
dndLog.fine("Event is already registered: " + e);
|
||||
}
|
||||
handler.unlock();
|
||||
}
|
||||
|
||||
void unregisterEvent(SunDropTargetEvent e) {
|
||||
handler.lock();
|
||||
try {
|
||||
if (!eventSet.remove(e)) {
|
||||
// This event has already been unregistered.
|
||||
return;
|
||||
}
|
||||
if (eventSet.isEmpty()) {
|
||||
if (!dispatcherDone && dispatchType == DISPATCH_SYNC) {
|
||||
handler.exit();
|
||||
}
|
||||
dispatcherDone = true;
|
||||
}
|
||||
} finally {
|
||||
handler.unlock();
|
||||
}
|
||||
|
||||
try {
|
||||
peer.eventProcessed(e, returnValue, dispatcherDone);
|
||||
} finally {
|
||||
/*
|
||||
* Clear the reference to the native context if all copies of
|
||||
* the original event are processed.
|
||||
*/
|
||||
if (dispatcherDone) {
|
||||
nativeCtxt = 0;
|
||||
// Fix for 6342381
|
||||
peer.nativeDragContext = 0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterAllEvents() {
|
||||
Object[] events = null;
|
||||
handler.lock();
|
||||
try {
|
||||
events = eventSet.toArray();
|
||||
} finally {
|
||||
handler.unlock();
|
||||
}
|
||||
|
||||
if (events != null) {
|
||||
for (int i = 0; i < events.length; i++) {
|
||||
unregisterEvent((SunDropTargetEvent)events[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
77
jdkSrc/jdk8/sun/awt/dnd/SunDropTargetEvent.java
Normal file
77
jdkSrc/jdk8/sun/awt/dnd/SunDropTargetEvent.java
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, 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.dnd;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.dnd.InvalidDnDOperationException;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
public class SunDropTargetEvent extends MouseEvent {
|
||||
|
||||
public static final int MOUSE_DROPPED = MouseEvent.MOUSE_RELEASED;
|
||||
|
||||
private final SunDropTargetContextPeer.EventDispatcher dispatcher;
|
||||
|
||||
public SunDropTargetEvent(Component source, int id, int x, int y,
|
||||
SunDropTargetContextPeer.EventDispatcher d) {
|
||||
super(source, id, System.currentTimeMillis(), 0, x, y, 0, 0, 0,
|
||||
false, MouseEvent.NOBUTTON);
|
||||
dispatcher = d;
|
||||
dispatcher.registerEvent(this);
|
||||
}
|
||||
|
||||
public void dispatch() {
|
||||
try {
|
||||
dispatcher.dispatchEvent(this);
|
||||
} finally {
|
||||
dispatcher.unregisterEvent(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void consume() {
|
||||
boolean was_consumed = isConsumed();
|
||||
super.consume();
|
||||
if (!was_consumed && isConsumed()) {
|
||||
dispatcher.unregisterEvent(this);
|
||||
}
|
||||
}
|
||||
|
||||
public SunDropTargetContextPeer.EventDispatcher getDispatcher() {
|
||||
return dispatcher;
|
||||
}
|
||||
|
||||
public String paramString() {
|
||||
String typeStr = null;
|
||||
|
||||
switch (id) {
|
||||
case MOUSE_DROPPED:
|
||||
typeStr = "MOUSE_DROPPED"; break;
|
||||
default:
|
||||
return super.paramString();
|
||||
}
|
||||
return typeStr + ",(" + getX() + "," + getY() + ")";
|
||||
}
|
||||
}
|
||||
42
jdkSrc/jdk8/sun/awt/event/IgnorePaintEvent.java
Normal file
42
jdkSrc/jdk8/sun/awt/event/IgnorePaintEvent.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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.event;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.PaintEvent;
|
||||
|
||||
/**
|
||||
* PaintEvents that are effectively ignored. This class is used only for
|
||||
* tagging. If a heavy weight peer is asked to handle an event of this
|
||||
* class it'll ignore it. This class is used by Swing.
|
||||
* Look at <code>javax.swing.SwingPaintEventDispatcher</code> for more.
|
||||
*
|
||||
*/
|
||||
public class IgnorePaintEvent extends PaintEvent {
|
||||
public IgnorePaintEvent(Component source, int id, Rectangle updateRect) {
|
||||
super(source, id, updateRect);
|
||||
}
|
||||
}
|
||||
561
jdkSrc/jdk8/sun/awt/geom/AreaOp.java
Normal file
561
jdkSrc/jdk8/sun/awt/geom/AreaOp.java
Normal file
@@ -0,0 +1,561 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2003, 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.geom;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Comparator;
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class AreaOp {
|
||||
public static abstract class CAGOp extends AreaOp {
|
||||
boolean inLeft;
|
||||
boolean inRight;
|
||||
boolean inResult;
|
||||
|
||||
public void newRow() {
|
||||
inLeft = false;
|
||||
inRight = false;
|
||||
inResult = false;
|
||||
}
|
||||
|
||||
public int classify(Edge e) {
|
||||
if (e.getCurveTag() == CTAG_LEFT) {
|
||||
inLeft = !inLeft;
|
||||
} else {
|
||||
inRight = !inRight;
|
||||
}
|
||||
boolean newClass = newClassification(inLeft, inRight);
|
||||
if (inResult == newClass) {
|
||||
return ETAG_IGNORE;
|
||||
}
|
||||
inResult = newClass;
|
||||
return (newClass ? ETAG_ENTER : ETAG_EXIT);
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return (inResult ? RSTAG_INSIDE : RSTAG_OUTSIDE);
|
||||
}
|
||||
|
||||
public abstract boolean newClassification(boolean inLeft,
|
||||
boolean inRight);
|
||||
}
|
||||
|
||||
public static class AddOp extends CAGOp {
|
||||
public boolean newClassification(boolean inLeft, boolean inRight) {
|
||||
return (inLeft || inRight);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SubOp extends CAGOp {
|
||||
public boolean newClassification(boolean inLeft, boolean inRight) {
|
||||
return (inLeft && !inRight);
|
||||
}
|
||||
}
|
||||
|
||||
public static class IntOp extends CAGOp {
|
||||
public boolean newClassification(boolean inLeft, boolean inRight) {
|
||||
return (inLeft && inRight);
|
||||
}
|
||||
}
|
||||
|
||||
public static class XorOp extends CAGOp {
|
||||
public boolean newClassification(boolean inLeft, boolean inRight) {
|
||||
return (inLeft != inRight);
|
||||
}
|
||||
}
|
||||
|
||||
public static class NZWindOp extends AreaOp {
|
||||
private int count;
|
||||
|
||||
public void newRow() {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
public int classify(Edge e) {
|
||||
// Note: the right curves should be an empty set with this op...
|
||||
// assert(e.getCurveTag() == CTAG_LEFT);
|
||||
int newCount = count;
|
||||
int type = (newCount == 0 ? ETAG_ENTER : ETAG_IGNORE);
|
||||
newCount += e.getCurve().getDirection();
|
||||
count = newCount;
|
||||
return (newCount == 0 ? ETAG_EXIT : type);
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return ((count == 0) ? RSTAG_OUTSIDE : RSTAG_INSIDE);
|
||||
}
|
||||
}
|
||||
|
||||
public static class EOWindOp extends AreaOp {
|
||||
private boolean inside;
|
||||
|
||||
public void newRow() {
|
||||
inside = false;
|
||||
}
|
||||
|
||||
public int classify(Edge e) {
|
||||
// Note: the right curves should be an empty set with this op...
|
||||
// assert(e.getCurveTag() == CTAG_LEFT);
|
||||
boolean newInside = !inside;
|
||||
inside = newInside;
|
||||
return (newInside ? ETAG_ENTER : ETAG_EXIT);
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return (inside ? RSTAG_INSIDE : RSTAG_OUTSIDE);
|
||||
}
|
||||
}
|
||||
|
||||
private AreaOp() {
|
||||
}
|
||||
|
||||
/* Constants to tag the left and right curves in the edge list */
|
||||
public static final int CTAG_LEFT = 0;
|
||||
public static final int CTAG_RIGHT = 1;
|
||||
|
||||
/* Constants to classify edges */
|
||||
public static final int ETAG_IGNORE = 0;
|
||||
public static final int ETAG_ENTER = 1;
|
||||
public static final int ETAG_EXIT = -1;
|
||||
|
||||
/* Constants used to classify result state */
|
||||
public static final int RSTAG_INSIDE = 1;
|
||||
public static final int RSTAG_OUTSIDE = -1;
|
||||
|
||||
public abstract void newRow();
|
||||
|
||||
public abstract int classify(Edge e);
|
||||
|
||||
public abstract int getState();
|
||||
|
||||
public Vector calculate(Vector left, Vector right) {
|
||||
Vector edges = new Vector();
|
||||
addEdges(edges, left, AreaOp.CTAG_LEFT);
|
||||
addEdges(edges, right, AreaOp.CTAG_RIGHT);
|
||||
edges = pruneEdges(edges);
|
||||
if (false) {
|
||||
System.out.println("result: ");
|
||||
int numcurves = edges.size();
|
||||
Curve[] curvelist = (Curve[]) edges.toArray(new Curve[numcurves]);
|
||||
for (int i = 0; i < numcurves; i++) {
|
||||
System.out.println("curvelist["+i+"] = "+curvelist[i]);
|
||||
}
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
private static void addEdges(Vector edges, Vector curves, int curvetag) {
|
||||
Enumeration enum_ = curves.elements();
|
||||
while (enum_.hasMoreElements()) {
|
||||
Curve c = (Curve) enum_.nextElement();
|
||||
if (c.getOrder() > 0) {
|
||||
edges.add(new Edge(c, curvetag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Comparator YXTopComparator = new Comparator() {
|
||||
public int compare(Object o1, Object o2) {
|
||||
Curve c1 = ((Edge) o1).getCurve();
|
||||
Curve c2 = ((Edge) o2).getCurve();
|
||||
double v1, v2;
|
||||
if ((v1 = c1.getYTop()) == (v2 = c2.getYTop())) {
|
||||
if ((v1 = c1.getXTop()) == (v2 = c2.getXTop())) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (v1 < v2) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
private Vector pruneEdges(Vector edges) {
|
||||
int numedges = edges.size();
|
||||
if (numedges < 2) {
|
||||
return edges;
|
||||
}
|
||||
Edge[] edgelist = (Edge[]) edges.toArray(new Edge[numedges]);
|
||||
Arrays.sort(edgelist, YXTopComparator);
|
||||
if (false) {
|
||||
System.out.println("pruning: ");
|
||||
for (int i = 0; i < numedges; i++) {
|
||||
System.out.println("edgelist["+i+"] = "+edgelist[i]);
|
||||
}
|
||||
}
|
||||
Edge e;
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int cur = 0;
|
||||
int next = 0;
|
||||
double yrange[] = new double[2];
|
||||
Vector subcurves = new Vector();
|
||||
Vector chains = new Vector();
|
||||
Vector links = new Vector();
|
||||
// Active edges are between left (inclusive) and right (exclusive)
|
||||
while (left < numedges) {
|
||||
double y = yrange[0];
|
||||
// Prune active edges that fall off the top of the active y range
|
||||
for (cur = next = right - 1; cur >= left; cur--) {
|
||||
e = edgelist[cur];
|
||||
if (e.getCurve().getYBot() > y) {
|
||||
if (next > cur) {
|
||||
edgelist[next] = e;
|
||||
}
|
||||
next--;
|
||||
}
|
||||
}
|
||||
left = next + 1;
|
||||
// Grab a new "top of Y range" if the active edges are empty
|
||||
if (left >= right) {
|
||||
if (right >= numedges) {
|
||||
break;
|
||||
}
|
||||
y = edgelist[right].getCurve().getYTop();
|
||||
if (y > yrange[0]) {
|
||||
finalizeSubCurves(subcurves, chains);
|
||||
}
|
||||
yrange[0] = y;
|
||||
}
|
||||
// Incorporate new active edges that enter the active y range
|
||||
while (right < numedges) {
|
||||
e = edgelist[right];
|
||||
if (e.getCurve().getYTop() > y) {
|
||||
break;
|
||||
}
|
||||
right++;
|
||||
}
|
||||
// Sort the current active edges by their X values and
|
||||
// determine the maximum valid Y range where the X ordering
|
||||
// is correct
|
||||
yrange[1] = edgelist[left].getCurve().getYBot();
|
||||
if (right < numedges) {
|
||||
y = edgelist[right].getCurve().getYTop();
|
||||
if (yrange[1] > y) {
|
||||
yrange[1] = y;
|
||||
}
|
||||
}
|
||||
if (false) {
|
||||
System.out.println("current line: y = ["+
|
||||
yrange[0]+", "+yrange[1]+"]");
|
||||
for (cur = left; cur < right; cur++) {
|
||||
System.out.println(" "+edgelist[cur]);
|
||||
}
|
||||
}
|
||||
// Note: We could start at left+1, but we need to make
|
||||
// sure that edgelist[left] has its equivalence set to 0.
|
||||
int nexteq = 1;
|
||||
for (cur = left; cur < right; cur++) {
|
||||
e = edgelist[cur];
|
||||
e.setEquivalence(0);
|
||||
for (next = cur; next > left; next--) {
|
||||
Edge prevedge = edgelist[next-1];
|
||||
int ordering = e.compareTo(prevedge, yrange);
|
||||
if (yrange[1] <= yrange[0]) {
|
||||
throw new InternalError("backstepping to "+yrange[1]+
|
||||
" from "+yrange[0]);
|
||||
}
|
||||
if (ordering >= 0) {
|
||||
if (ordering == 0) {
|
||||
// If the curves are equal, mark them to be
|
||||
// deleted later if they cancel each other
|
||||
// out so that we avoid having extraneous
|
||||
// curve segments.
|
||||
int eq = prevedge.getEquivalence();
|
||||
if (eq == 0) {
|
||||
eq = nexteq++;
|
||||
prevedge.setEquivalence(eq);
|
||||
}
|
||||
e.setEquivalence(eq);
|
||||
}
|
||||
break;
|
||||
}
|
||||
edgelist[next] = prevedge;
|
||||
}
|
||||
edgelist[next] = e;
|
||||
}
|
||||
if (false) {
|
||||
System.out.println("current sorted line: y = ["+
|
||||
yrange[0]+", "+yrange[1]+"]");
|
||||
for (cur = left; cur < right; cur++) {
|
||||
System.out.println(" "+edgelist[cur]);
|
||||
}
|
||||
}
|
||||
// Now prune the active edge list.
|
||||
// For each edge in the list, determine its classification
|
||||
// (entering shape, exiting shape, ignore - no change) and
|
||||
// record the current Y range and its classification in the
|
||||
// Edge object for use later in constructing the new outline.
|
||||
newRow();
|
||||
double ystart = yrange[0];
|
||||
double yend = yrange[1];
|
||||
for (cur = left; cur < right; cur++) {
|
||||
e = edgelist[cur];
|
||||
int etag;
|
||||
int eq = e.getEquivalence();
|
||||
if (eq != 0) {
|
||||
// Find one of the segments in the "equal" range
|
||||
// with the right transition state and prefer an
|
||||
// edge that was either active up until ystart
|
||||
// or the edge that extends the furthest downward
|
||||
// (i.e. has the most potential for continuation)
|
||||
int origstate = getState();
|
||||
etag = (origstate == AreaOp.RSTAG_INSIDE
|
||||
? AreaOp.ETAG_EXIT
|
||||
: AreaOp.ETAG_ENTER);
|
||||
Edge activematch = null;
|
||||
Edge longestmatch = e;
|
||||
double furthesty = yend;
|
||||
do {
|
||||
// Note: classify() must be called
|
||||
// on every edge we consume here.
|
||||
classify(e);
|
||||
if (activematch == null &&
|
||||
e.isActiveFor(ystart, etag))
|
||||
{
|
||||
activematch = e;
|
||||
}
|
||||
y = e.getCurve().getYBot();
|
||||
if (y > furthesty) {
|
||||
longestmatch = e;
|
||||
furthesty = y;
|
||||
}
|
||||
} while (++cur < right &&
|
||||
(e = edgelist[cur]).getEquivalence() == eq);
|
||||
--cur;
|
||||
if (getState() == origstate) {
|
||||
etag = AreaOp.ETAG_IGNORE;
|
||||
} else {
|
||||
e = (activematch != null ? activematch : longestmatch);
|
||||
}
|
||||
} else {
|
||||
etag = classify(e);
|
||||
}
|
||||
if (etag != AreaOp.ETAG_IGNORE) {
|
||||
e.record(yend, etag);
|
||||
links.add(new CurveLink(e.getCurve(), ystart, yend, etag));
|
||||
}
|
||||
}
|
||||
// assert(getState() == AreaOp.RSTAG_OUTSIDE);
|
||||
if (getState() != AreaOp.RSTAG_OUTSIDE) {
|
||||
System.out.println("Still inside at end of active edge list!");
|
||||
System.out.println("num curves = "+(right-left));
|
||||
System.out.println("num links = "+links.size());
|
||||
System.out.println("y top = "+yrange[0]);
|
||||
if (right < numedges) {
|
||||
System.out.println("y top of next curve = "+
|
||||
edgelist[right].getCurve().getYTop());
|
||||
} else {
|
||||
System.out.println("no more curves");
|
||||
}
|
||||
for (cur = left; cur < right; cur++) {
|
||||
e = edgelist[cur];
|
||||
System.out.println(e);
|
||||
int eq = e.getEquivalence();
|
||||
if (eq != 0) {
|
||||
System.out.println(" was equal to "+eq+"...");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (false) {
|
||||
System.out.println("new links:");
|
||||
for (int i = 0; i < links.size(); i++) {
|
||||
CurveLink link = (CurveLink) links.elementAt(i);
|
||||
System.out.println(" "+link.getSubCurve());
|
||||
}
|
||||
}
|
||||
resolveLinks(subcurves, chains, links);
|
||||
links.clear();
|
||||
// Finally capture the bottom of the valid Y range as the top
|
||||
// of the next Y range.
|
||||
yrange[0] = yend;
|
||||
}
|
||||
finalizeSubCurves(subcurves, chains);
|
||||
Vector ret = new Vector();
|
||||
Enumeration enum_ = subcurves.elements();
|
||||
while (enum_.hasMoreElements()) {
|
||||
CurveLink link = (CurveLink) enum_.nextElement();
|
||||
ret.add(link.getMoveto());
|
||||
CurveLink nextlink = link;
|
||||
while ((nextlink = nextlink.getNext()) != null) {
|
||||
if (!link.absorb(nextlink)) {
|
||||
ret.add(link.getSubCurve());
|
||||
link = nextlink;
|
||||
}
|
||||
}
|
||||
ret.add(link.getSubCurve());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void finalizeSubCurves(Vector subcurves, Vector chains) {
|
||||
int numchains = chains.size();
|
||||
if (numchains == 0) {
|
||||
return;
|
||||
}
|
||||
if ((numchains & 1) != 0) {
|
||||
throw new InternalError("Odd number of chains!");
|
||||
}
|
||||
ChainEnd[] endlist = new ChainEnd[numchains];
|
||||
chains.toArray(endlist);
|
||||
for (int i = 1; i < numchains; i += 2) {
|
||||
ChainEnd open = endlist[i - 1];
|
||||
ChainEnd close = endlist[i];
|
||||
CurveLink subcurve = open.linkTo(close);
|
||||
if (subcurve != null) {
|
||||
subcurves.add(subcurve);
|
||||
}
|
||||
}
|
||||
chains.clear();
|
||||
}
|
||||
|
||||
private static CurveLink[] EmptyLinkList = new CurveLink[2];
|
||||
private static ChainEnd[] EmptyChainList = new ChainEnd[2];
|
||||
|
||||
public static void resolveLinks(Vector subcurves,
|
||||
Vector chains,
|
||||
Vector links)
|
||||
{
|
||||
int numlinks = links.size();
|
||||
CurveLink[] linklist;
|
||||
if (numlinks == 0) {
|
||||
linklist = EmptyLinkList;
|
||||
} else {
|
||||
if ((numlinks & 1) != 0) {
|
||||
throw new InternalError("Odd number of new curves!");
|
||||
}
|
||||
linklist = new CurveLink[numlinks+2];
|
||||
links.toArray(linklist);
|
||||
}
|
||||
int numchains = chains.size();
|
||||
ChainEnd[] endlist;
|
||||
if (numchains == 0) {
|
||||
endlist = EmptyChainList;
|
||||
} else {
|
||||
if ((numchains & 1) != 0) {
|
||||
throw new InternalError("Odd number of chains!");
|
||||
}
|
||||
endlist = new ChainEnd[numchains+2];
|
||||
chains.toArray(endlist);
|
||||
}
|
||||
int curchain = 0;
|
||||
int curlink = 0;
|
||||
chains.clear();
|
||||
ChainEnd chain = endlist[0];
|
||||
ChainEnd nextchain = endlist[1];
|
||||
CurveLink link = linklist[0];
|
||||
CurveLink nextlink = linklist[1];
|
||||
while (chain != null || link != null) {
|
||||
/*
|
||||
* Strategy 1:
|
||||
* Connect chains or links if they are the only things left...
|
||||
*/
|
||||
boolean connectchains = (link == null);
|
||||
boolean connectlinks = (chain == null);
|
||||
|
||||
if (!connectchains && !connectlinks) {
|
||||
// assert(link != null && chain != null);
|
||||
/*
|
||||
* Strategy 2:
|
||||
* Connect chains or links if they close off an open area...
|
||||
*/
|
||||
connectchains = ((curchain & 1) == 0 &&
|
||||
chain.getX() == nextchain.getX());
|
||||
connectlinks = ((curlink & 1) == 0 &&
|
||||
link.getX() == nextlink.getX());
|
||||
|
||||
if (!connectchains && !connectlinks) {
|
||||
/*
|
||||
* Strategy 3:
|
||||
* Connect chains or links if their successor is
|
||||
* between them and their potential connectee...
|
||||
*/
|
||||
double cx = chain.getX();
|
||||
double lx = link.getX();
|
||||
connectchains =
|
||||
(nextchain != null && cx < lx &&
|
||||
obstructs(nextchain.getX(), lx, curchain));
|
||||
connectlinks =
|
||||
(nextlink != null && lx < cx &&
|
||||
obstructs(nextlink.getX(), cx, curlink));
|
||||
}
|
||||
}
|
||||
if (connectchains) {
|
||||
CurveLink subcurve = chain.linkTo(nextchain);
|
||||
if (subcurve != null) {
|
||||
subcurves.add(subcurve);
|
||||
}
|
||||
curchain += 2;
|
||||
chain = endlist[curchain];
|
||||
nextchain = endlist[curchain+1];
|
||||
}
|
||||
if (connectlinks) {
|
||||
ChainEnd openend = new ChainEnd(link, null);
|
||||
ChainEnd closeend = new ChainEnd(nextlink, openend);
|
||||
openend.setOtherEnd(closeend);
|
||||
chains.add(openend);
|
||||
chains.add(closeend);
|
||||
curlink += 2;
|
||||
link = linklist[curlink];
|
||||
nextlink = linklist[curlink+1];
|
||||
}
|
||||
if (!connectchains && !connectlinks) {
|
||||
// assert(link != null);
|
||||
// assert(chain != null);
|
||||
// assert(chain.getEtag() == link.getEtag());
|
||||
chain.addLink(link);
|
||||
chains.add(chain);
|
||||
curchain++;
|
||||
chain = nextchain;
|
||||
nextchain = endlist[curchain+1];
|
||||
curlink++;
|
||||
link = nextlink;
|
||||
nextlink = linklist[curlink+1];
|
||||
}
|
||||
}
|
||||
if ((chains.size() & 1) != 0) {
|
||||
System.out.println("Odd number of chains!");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Does the position of the next edge at v1 "obstruct" the
|
||||
* connectivity between current edge and the potential
|
||||
* partner edge which is positioned at v2?
|
||||
*
|
||||
* Phase tells us whether we are testing for a transition
|
||||
* into or out of the interior part of the resulting area.
|
||||
*
|
||||
* Require 4-connected continuity if this edge and the partner
|
||||
* edge are both "entering into" type edges
|
||||
* Allow 8-connected continuity for "exiting from" type edges
|
||||
*/
|
||||
public static boolean obstructs(double v1, double v2, int phase) {
|
||||
return (((phase & 1) == 0) ? (v1 <= v2) : (v1 < v2));
|
||||
}
|
||||
}
|
||||
117
jdkSrc/jdk8/sun/awt/geom/ChainEnd.java
Normal file
117
jdkSrc/jdk8/sun/awt/geom/ChainEnd.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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.geom;
|
||||
|
||||
final class ChainEnd {
|
||||
CurveLink head;
|
||||
CurveLink tail;
|
||||
ChainEnd partner;
|
||||
int etag;
|
||||
|
||||
public ChainEnd(CurveLink first, ChainEnd partner) {
|
||||
this.head = first;
|
||||
this.tail = first;
|
||||
this.partner = partner;
|
||||
this.etag = first.getEdgeTag();
|
||||
}
|
||||
|
||||
public CurveLink getChain() {
|
||||
return head;
|
||||
}
|
||||
|
||||
public void setOtherEnd(ChainEnd partner) {
|
||||
this.partner = partner;
|
||||
}
|
||||
|
||||
public ChainEnd getPartner() {
|
||||
return partner;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns head of a complete chain to be added to subcurves
|
||||
* or null if the links did not complete such a chain.
|
||||
*/
|
||||
public CurveLink linkTo(ChainEnd that) {
|
||||
if (etag == AreaOp.ETAG_IGNORE ||
|
||||
that.etag == AreaOp.ETAG_IGNORE)
|
||||
{
|
||||
throw new InternalError("ChainEnd linked more than once!");
|
||||
}
|
||||
if (etag == that.etag) {
|
||||
throw new InternalError("Linking chains of the same type!");
|
||||
}
|
||||
ChainEnd enter, exit;
|
||||
// assert(partner.etag != that.partner.etag);
|
||||
if (etag == AreaOp.ETAG_ENTER) {
|
||||
enter = this;
|
||||
exit = that;
|
||||
} else {
|
||||
enter = that;
|
||||
exit = this;
|
||||
}
|
||||
// Now make sure these ChainEnds are not linked to any others...
|
||||
etag = AreaOp.ETAG_IGNORE;
|
||||
that.etag = AreaOp.ETAG_IGNORE;
|
||||
// Now link everything up...
|
||||
enter.tail.setNext(exit.head);
|
||||
enter.tail = exit.tail;
|
||||
if (partner == that) {
|
||||
// Curve has closed on itself...
|
||||
return enter.head;
|
||||
}
|
||||
// Link this chain into one end of the chain formed by the partners
|
||||
ChainEnd otherenter = exit.partner;
|
||||
ChainEnd otherexit = enter.partner;
|
||||
otherenter.partner = otherexit;
|
||||
otherexit.partner = otherenter;
|
||||
if (enter.head.getYTop() < otherenter.head.getYTop()) {
|
||||
enter.tail.setNext(otherenter.head);
|
||||
otherenter.head = enter.head;
|
||||
} else {
|
||||
otherexit.tail.setNext(enter.head);
|
||||
otherexit.tail = enter.tail;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addLink(CurveLink newlink) {
|
||||
if (etag == AreaOp.ETAG_ENTER) {
|
||||
tail.setNext(newlink);
|
||||
tail = newlink;
|
||||
} else {
|
||||
newlink.setNext(head);
|
||||
head = newlink;
|
||||
}
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
if (etag == AreaOp.ETAG_ENTER) {
|
||||
return tail.getXBot();
|
||||
} else {
|
||||
return head.getXBot();
|
||||
}
|
||||
}
|
||||
}
|
||||
522
jdkSrc/jdk8/sun/awt/geom/Crossings.java
Normal file
522
jdkSrc/jdk8/sun/awt/geom/Crossings.java
Normal file
@@ -0,0 +1,522 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2003, 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.geom;
|
||||
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public abstract class Crossings {
|
||||
public static final boolean debug = false;
|
||||
|
||||
int limit = 0;
|
||||
double yranges[] = new double[10];
|
||||
|
||||
double xlo, ylo, xhi, yhi;
|
||||
|
||||
public Crossings(double xlo, double ylo, double xhi, double yhi) {
|
||||
this.xlo = xlo;
|
||||
this.ylo = ylo;
|
||||
this.xhi = xhi;
|
||||
this.yhi = yhi;
|
||||
}
|
||||
|
||||
public final double getXLo() {
|
||||
return xlo;
|
||||
}
|
||||
|
||||
public final double getYLo() {
|
||||
return ylo;
|
||||
}
|
||||
|
||||
public final double getXHi() {
|
||||
return xhi;
|
||||
}
|
||||
|
||||
public final double getYHi() {
|
||||
return yhi;
|
||||
}
|
||||
|
||||
public abstract void record(double ystart, double yend, int direction);
|
||||
|
||||
public void print() {
|
||||
System.out.println("Crossings [");
|
||||
System.out.println(" bounds = ["+ylo+", "+yhi+"]");
|
||||
for (int i = 0; i < limit; i += 2) {
|
||||
System.out.println(" ["+yranges[i]+", "+yranges[i+1]+"]");
|
||||
}
|
||||
System.out.println("]");
|
||||
}
|
||||
|
||||
public final boolean isEmpty() {
|
||||
return (limit == 0);
|
||||
}
|
||||
|
||||
public abstract boolean covers(double ystart, double yend);
|
||||
|
||||
public static Crossings findCrossings(Vector curves,
|
||||
double xlo, double ylo,
|
||||
double xhi, double yhi)
|
||||
{
|
||||
Crossings cross = new EvenOdd(xlo, ylo, xhi, yhi);
|
||||
Enumeration enum_ = curves.elements();
|
||||
while (enum_.hasMoreElements()) {
|
||||
Curve c = (Curve) enum_.nextElement();
|
||||
if (c.accumulateCrossings(cross)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
cross.print();
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
|
||||
public static Crossings findCrossings(PathIterator pi,
|
||||
double xlo, double ylo,
|
||||
double xhi, double yhi)
|
||||
{
|
||||
Crossings cross;
|
||||
if (pi.getWindingRule() == pi.WIND_EVEN_ODD) {
|
||||
cross = new EvenOdd(xlo, ylo, xhi, yhi);
|
||||
} else {
|
||||
cross = new NonZero(xlo, ylo, xhi, yhi);
|
||||
}
|
||||
// coords array is big enough for holding:
|
||||
// coordinates returned from currentSegment (6)
|
||||
// OR
|
||||
// two subdivided quadratic curves (2+4+4=10)
|
||||
// AND
|
||||
// 0-1 horizontal splitting parameters
|
||||
// OR
|
||||
// 2 parametric equation derivative coefficients
|
||||
// OR
|
||||
// three subdivided cubic curves (2+6+6+6=20)
|
||||
// AND
|
||||
// 0-2 horizontal splitting parameters
|
||||
// OR
|
||||
// 3 parametric equation derivative coefficients
|
||||
double coords[] = new double[23];
|
||||
double movx = 0;
|
||||
double movy = 0;
|
||||
double curx = 0;
|
||||
double cury = 0;
|
||||
double newx, newy;
|
||||
while (!pi.isDone()) {
|
||||
int type = pi.currentSegment(coords);
|
||||
switch (type) {
|
||||
case PathIterator.SEG_MOVETO:
|
||||
if (movy != cury &&
|
||||
cross.accumulateLine(curx, cury, movx, movy))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
movx = curx = coords[0];
|
||||
movy = cury = coords[1];
|
||||
break;
|
||||
case PathIterator.SEG_LINETO:
|
||||
newx = coords[0];
|
||||
newy = coords[1];
|
||||
if (cross.accumulateLine(curx, cury, newx, newy)) {
|
||||
return null;
|
||||
}
|
||||
curx = newx;
|
||||
cury = newy;
|
||||
break;
|
||||
case PathIterator.SEG_QUADTO:
|
||||
newx = coords[2];
|
||||
newy = coords[3];
|
||||
if (cross.accumulateQuad(curx, cury, coords)) {
|
||||
return null;
|
||||
}
|
||||
curx = newx;
|
||||
cury = newy;
|
||||
break;
|
||||
case PathIterator.SEG_CUBICTO:
|
||||
newx = coords[4];
|
||||
newy = coords[5];
|
||||
if (cross.accumulateCubic(curx, cury, coords)) {
|
||||
return null;
|
||||
}
|
||||
curx = newx;
|
||||
cury = newy;
|
||||
break;
|
||||
case PathIterator.SEG_CLOSE:
|
||||
if (movy != cury &&
|
||||
cross.accumulateLine(curx, cury, movx, movy))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
curx = movx;
|
||||
cury = movy;
|
||||
break;
|
||||
}
|
||||
pi.next();
|
||||
}
|
||||
if (movy != cury) {
|
||||
if (cross.accumulateLine(curx, cury, movx, movy)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
cross.print();
|
||||
}
|
||||
return cross;
|
||||
}
|
||||
|
||||
public boolean accumulateLine(double x0, double y0,
|
||||
double x1, double y1)
|
||||
{
|
||||
if (y0 <= y1) {
|
||||
return accumulateLine(x0, y0, x1, y1, 1);
|
||||
} else {
|
||||
return accumulateLine(x1, y1, x0, y0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean accumulateLine(double x0, double y0,
|
||||
double x1, double y1,
|
||||
int direction)
|
||||
{
|
||||
if (yhi <= y0 || ylo >= y1) {
|
||||
return false;
|
||||
}
|
||||
if (x0 >= xhi && x1 >= xhi) {
|
||||
return false;
|
||||
}
|
||||
if (y0 == y1) {
|
||||
return (x0 >= xlo || x1 >= xlo);
|
||||
}
|
||||
double xstart, ystart, xend, yend;
|
||||
double dx = (x1 - x0);
|
||||
double dy = (y1 - y0);
|
||||
if (y0 < ylo) {
|
||||
xstart = x0 + (ylo - y0) * dx / dy;
|
||||
ystart = ylo;
|
||||
} else {
|
||||
xstart = x0;
|
||||
ystart = y0;
|
||||
}
|
||||
if (yhi < y1) {
|
||||
xend = x0 + (yhi - y0) * dx / dy;
|
||||
yend = yhi;
|
||||
} else {
|
||||
xend = x1;
|
||||
yend = y1;
|
||||
}
|
||||
if (xstart >= xhi && xend >= xhi) {
|
||||
return false;
|
||||
}
|
||||
if (xstart > xlo || xend > xlo) {
|
||||
return true;
|
||||
}
|
||||
record(ystart, yend, direction);
|
||||
return false;
|
||||
}
|
||||
|
||||
private Vector tmp = new Vector();
|
||||
|
||||
public boolean accumulateQuad(double x0, double y0, double coords[]) {
|
||||
if (y0 < ylo && coords[1] < ylo && coords[3] < ylo) {
|
||||
return false;
|
||||
}
|
||||
if (y0 > yhi && coords[1] > yhi && coords[3] > yhi) {
|
||||
return false;
|
||||
}
|
||||
if (x0 > xhi && coords[0] > xhi && coords[2] > xhi) {
|
||||
return false;
|
||||
}
|
||||
if (x0 < xlo && coords[0] < xlo && coords[2] < xlo) {
|
||||
if (y0 < coords[3]) {
|
||||
record(Math.max(y0, ylo), Math.min(coords[3], yhi), 1);
|
||||
} else if (y0 > coords[3]) {
|
||||
record(Math.max(coords[3], ylo), Math.min(y0, yhi), -1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Curve.insertQuad(tmp, x0, y0, coords);
|
||||
Enumeration enum_ = tmp.elements();
|
||||
while (enum_.hasMoreElements()) {
|
||||
Curve c = (Curve) enum_.nextElement();
|
||||
if (c.accumulateCrossings(this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
tmp.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean accumulateCubic(double x0, double y0, double coords[]) {
|
||||
if (y0 < ylo && coords[1] < ylo &&
|
||||
coords[3] < ylo && coords[5] < ylo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (y0 > yhi && coords[1] > yhi &&
|
||||
coords[3] > yhi && coords[5] > yhi)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (x0 > xhi && coords[0] > xhi &&
|
||||
coords[2] > xhi && coords[4] > xhi)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (x0 < xlo && coords[0] < xlo &&
|
||||
coords[2] < xlo && coords[4] < xlo)
|
||||
{
|
||||
if (y0 <= coords[5]) {
|
||||
record(Math.max(y0, ylo), Math.min(coords[5], yhi), 1);
|
||||
} else {
|
||||
record(Math.max(coords[5], ylo), Math.min(y0, yhi), -1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Curve.insertCubic(tmp, x0, y0, coords);
|
||||
Enumeration enum_ = tmp.elements();
|
||||
while (enum_.hasMoreElements()) {
|
||||
Curve c = (Curve) enum_.nextElement();
|
||||
if (c.accumulateCrossings(this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
tmp.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
public final static class EvenOdd extends Crossings {
|
||||
public EvenOdd(double xlo, double ylo, double xhi, double yhi) {
|
||||
super(xlo, ylo, xhi, yhi);
|
||||
}
|
||||
|
||||
public final boolean covers(double ystart, double yend) {
|
||||
return (limit == 2 && yranges[0] <= ystart && yranges[1] >= yend);
|
||||
}
|
||||
|
||||
public void record(double ystart, double yend, int direction) {
|
||||
if (ystart >= yend) {
|
||||
return;
|
||||
}
|
||||
int from = 0;
|
||||
// Quickly jump over all pairs that are completely "above"
|
||||
while (from < limit && ystart > yranges[from+1]) {
|
||||
from += 2;
|
||||
}
|
||||
int to = from;
|
||||
while (from < limit) {
|
||||
double yrlo = yranges[from++];
|
||||
double yrhi = yranges[from++];
|
||||
if (yend < yrlo) {
|
||||
// Quickly handle insertion of the new range
|
||||
yranges[to++] = ystart;
|
||||
yranges[to++] = yend;
|
||||
ystart = yrlo;
|
||||
yend = yrhi;
|
||||
continue;
|
||||
}
|
||||
// The ranges overlap - sort, collapse, insert, iterate
|
||||
double yll, ylh, yhl, yhh;
|
||||
if (ystart < yrlo) {
|
||||
yll = ystart;
|
||||
ylh = yrlo;
|
||||
} else {
|
||||
yll = yrlo;
|
||||
ylh = ystart;
|
||||
}
|
||||
if (yend < yrhi) {
|
||||
yhl = yend;
|
||||
yhh = yrhi;
|
||||
} else {
|
||||
yhl = yrhi;
|
||||
yhh = yend;
|
||||
}
|
||||
if (ylh == yhl) {
|
||||
ystart = yll;
|
||||
yend = yhh;
|
||||
} else {
|
||||
if (ylh > yhl) {
|
||||
ystart = yhl;
|
||||
yhl = ylh;
|
||||
ylh = ystart;
|
||||
}
|
||||
if (yll != ylh) {
|
||||
yranges[to++] = yll;
|
||||
yranges[to++] = ylh;
|
||||
}
|
||||
ystart = yhl;
|
||||
yend = yhh;
|
||||
}
|
||||
if (ystart >= yend) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (to < from && from < limit) {
|
||||
System.arraycopy(yranges, from, yranges, to, limit-from);
|
||||
}
|
||||
to += (limit-from);
|
||||
if (ystart < yend) {
|
||||
if (to >= yranges.length) {
|
||||
double newranges[] = new double[to+10];
|
||||
System.arraycopy(yranges, 0, newranges, 0, to);
|
||||
yranges = newranges;
|
||||
}
|
||||
yranges[to++] = ystart;
|
||||
yranges[to++] = yend;
|
||||
}
|
||||
limit = to;
|
||||
}
|
||||
}
|
||||
|
||||
public final static class NonZero extends Crossings {
|
||||
private int crosscounts[];
|
||||
|
||||
public NonZero(double xlo, double ylo, double xhi, double yhi) {
|
||||
super(xlo, ylo, xhi, yhi);
|
||||
crosscounts = new int[yranges.length / 2];
|
||||
}
|
||||
|
||||
public final boolean covers(double ystart, double yend) {
|
||||
int i = 0;
|
||||
while (i < limit) {
|
||||
double ylo = yranges[i++];
|
||||
double yhi = yranges[i++];
|
||||
if (ystart >= yhi) {
|
||||
continue;
|
||||
}
|
||||
if (ystart < ylo) {
|
||||
return false;
|
||||
}
|
||||
if (yend <= yhi) {
|
||||
return true;
|
||||
}
|
||||
ystart = yhi;
|
||||
}
|
||||
return (ystart >= yend);
|
||||
}
|
||||
|
||||
public void remove(int cur) {
|
||||
limit -= 2;
|
||||
int rem = limit - cur;
|
||||
if (rem > 0) {
|
||||
System.arraycopy(yranges, cur+2, yranges, cur, rem);
|
||||
System.arraycopy(crosscounts, cur/2+1,
|
||||
crosscounts, cur/2,
|
||||
rem/2);
|
||||
}
|
||||
}
|
||||
|
||||
public void insert(int cur, double lo, double hi, int dir) {
|
||||
int rem = limit - cur;
|
||||
double oldranges[] = yranges;
|
||||
int oldcounts[] = crosscounts;
|
||||
if (limit >= yranges.length) {
|
||||
yranges = new double[limit+10];
|
||||
System.arraycopy(oldranges, 0, yranges, 0, cur);
|
||||
crosscounts = new int[(limit+10)/2];
|
||||
System.arraycopy(oldcounts, 0, crosscounts, 0, cur/2);
|
||||
}
|
||||
if (rem > 0) {
|
||||
System.arraycopy(oldranges, cur, yranges, cur+2, rem);
|
||||
System.arraycopy(oldcounts, cur/2,
|
||||
crosscounts, cur/2+1,
|
||||
rem/2);
|
||||
}
|
||||
yranges[cur+0] = lo;
|
||||
yranges[cur+1] = hi;
|
||||
crosscounts[cur/2] = dir;
|
||||
limit += 2;
|
||||
}
|
||||
|
||||
public void record(double ystart, double yend, int direction) {
|
||||
if (ystart >= yend) {
|
||||
return;
|
||||
}
|
||||
int cur = 0;
|
||||
// Quickly jump over all pairs that are completely "above"
|
||||
while (cur < limit && ystart > yranges[cur+1]) {
|
||||
cur += 2;
|
||||
}
|
||||
if (cur < limit) {
|
||||
int rdir = crosscounts[cur/2];
|
||||
double yrlo = yranges[cur+0];
|
||||
double yrhi = yranges[cur+1];
|
||||
if (yrhi == ystart && rdir == direction) {
|
||||
// Remove the range from the list and collapse it
|
||||
// into the range being inserted. Note that the
|
||||
// new combined range may overlap the following range
|
||||
// so we must not simply combine the ranges in place
|
||||
// unless we are at the last range.
|
||||
if (cur+2 == limit) {
|
||||
yranges[cur+1] = yend;
|
||||
return;
|
||||
}
|
||||
remove(cur);
|
||||
ystart = yrlo;
|
||||
rdir = crosscounts[cur/2];
|
||||
yrlo = yranges[cur+0];
|
||||
yrhi = yranges[cur+1];
|
||||
}
|
||||
if (yend < yrlo) {
|
||||
// Just insert the new range at the current location
|
||||
insert(cur, ystart, yend, direction);
|
||||
return;
|
||||
}
|
||||
if (yend == yrlo && rdir == direction) {
|
||||
// Just prepend the new range to the current one
|
||||
yranges[cur] = ystart;
|
||||
return;
|
||||
}
|
||||
// The ranges must overlap - (yend > yrlo && yrhi > ystart)
|
||||
if (ystart < yrlo) {
|
||||
insert(cur, ystart, yrlo, direction);
|
||||
cur += 2;
|
||||
ystart = yrlo;
|
||||
} else if (yrlo < ystart) {
|
||||
insert(cur, yrlo, ystart, rdir);
|
||||
cur += 2;
|
||||
yrlo = ystart;
|
||||
}
|
||||
// assert(yrlo == ystart);
|
||||
int newdir = rdir + direction;
|
||||
double newend = Math.min(yend, yrhi);
|
||||
if (newdir == 0) {
|
||||
remove(cur);
|
||||
} else {
|
||||
crosscounts[cur/2] = newdir;
|
||||
yranges[cur++] = ystart;
|
||||
yranges[cur++] = newend;
|
||||
}
|
||||
ystart = yrlo = newend;
|
||||
if (yrlo < yrhi) {
|
||||
insert(cur, yrlo, yrhi, rdir);
|
||||
}
|
||||
}
|
||||
if (ystart < yend) {
|
||||
insert(cur, ystart, yend, direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1206
jdkSrc/jdk8/sun/awt/geom/Curve.java
Normal file
1206
jdkSrc/jdk8/sun/awt/geom/Curve.java
Normal file
File diff suppressed because it is too large
Load Diff
114
jdkSrc/jdk8/sun/awt/geom/CurveLink.java
Normal file
114
jdkSrc/jdk8/sun/awt/geom/CurveLink.java
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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.geom;
|
||||
|
||||
final class CurveLink {
|
||||
Curve curve;
|
||||
double ytop;
|
||||
double ybot;
|
||||
int etag;
|
||||
|
||||
CurveLink next;
|
||||
|
||||
public CurveLink(Curve curve, double ystart, double yend, int etag) {
|
||||
this.curve = curve;
|
||||
this.ytop = ystart;
|
||||
this.ybot = yend;
|
||||
this.etag = etag;
|
||||
if (ytop < curve.getYTop() || ybot > curve.getYBot()) {
|
||||
throw new InternalError("bad curvelink ["+ytop+"=>"+ybot+"] for "+curve);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean absorb(CurveLink link) {
|
||||
return absorb(link.curve, link.ytop, link.ybot, link.etag);
|
||||
}
|
||||
|
||||
public boolean absorb(Curve curve, double ystart, double yend, int etag) {
|
||||
if (this.curve != curve || this.etag != etag ||
|
||||
ybot < ystart || ytop > yend)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (ystart < curve.getYTop() || yend > curve.getYBot()) {
|
||||
throw new InternalError("bad curvelink ["+ystart+"=>"+yend+"] for "+curve);
|
||||
}
|
||||
this.ytop = Math.min(ytop, ystart);
|
||||
this.ybot = Math.max(ybot, yend);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (ytop == ybot);
|
||||
}
|
||||
|
||||
public Curve getCurve() {
|
||||
return curve;
|
||||
}
|
||||
|
||||
public Curve getSubCurve() {
|
||||
if (ytop == curve.getYTop() && ybot == curve.getYBot()) {
|
||||
return curve.getWithDirection(etag);
|
||||
}
|
||||
return curve.getSubCurve(ytop, ybot, etag);
|
||||
}
|
||||
|
||||
public Curve getMoveto() {
|
||||
return new Order0(getXTop(), getYTop());
|
||||
}
|
||||
|
||||
public double getXTop() {
|
||||
return curve.XforY(ytop);
|
||||
}
|
||||
|
||||
public double getYTop() {
|
||||
return ytop;
|
||||
}
|
||||
|
||||
public double getXBot() {
|
||||
return curve.XforY(ybot);
|
||||
}
|
||||
|
||||
public double getYBot() {
|
||||
return ybot;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return curve.XforY(ytop);
|
||||
}
|
||||
|
||||
public int getEdgeTag() {
|
||||
return etag;
|
||||
}
|
||||
|
||||
public void setNext(CurveLink link) {
|
||||
this.next = link;
|
||||
}
|
||||
|
||||
public CurveLink getNext() {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
125
jdkSrc/jdk8/sun/awt/geom/Edge.java
Normal file
125
jdkSrc/jdk8/sun/awt/geom/Edge.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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.geom;
|
||||
|
||||
final class Edge {
|
||||
static final int INIT_PARTS = 4;
|
||||
static final int GROW_PARTS = 10;
|
||||
|
||||
Curve curve;
|
||||
int ctag;
|
||||
int etag;
|
||||
double activey;
|
||||
int equivalence;
|
||||
|
||||
public Edge(Curve c, int ctag) {
|
||||
this(c, ctag, AreaOp.ETAG_IGNORE);
|
||||
}
|
||||
|
||||
public Edge(Curve c, int ctag, int etag) {
|
||||
this.curve = c;
|
||||
this.ctag = ctag;
|
||||
this.etag = etag;
|
||||
}
|
||||
|
||||
public Curve getCurve() {
|
||||
return curve;
|
||||
}
|
||||
|
||||
public int getCurveTag() {
|
||||
return ctag;
|
||||
}
|
||||
|
||||
public int getEdgeTag() {
|
||||
return etag;
|
||||
}
|
||||
|
||||
public void setEdgeTag(int etag) {
|
||||
this.etag = etag;
|
||||
}
|
||||
|
||||
public int getEquivalence() {
|
||||
return equivalence;
|
||||
}
|
||||
|
||||
public void setEquivalence(int eq) {
|
||||
equivalence = eq;
|
||||
}
|
||||
|
||||
private Edge lastEdge;
|
||||
private int lastResult;
|
||||
private double lastLimit;
|
||||
|
||||
public int compareTo(Edge other, double yrange[]) {
|
||||
if (other == lastEdge && yrange[0] < lastLimit) {
|
||||
if (yrange[1] > lastLimit) {
|
||||
yrange[1] = lastLimit;
|
||||
}
|
||||
return lastResult;
|
||||
}
|
||||
if (this == other.lastEdge && yrange[0] < other.lastLimit) {
|
||||
if (yrange[1] > other.lastLimit) {
|
||||
yrange[1] = other.lastLimit;
|
||||
}
|
||||
return 0-other.lastResult;
|
||||
}
|
||||
//long start = System.currentTimeMillis();
|
||||
int ret = curve.compareTo(other.curve, yrange);
|
||||
//long end = System.currentTimeMillis();
|
||||
/*
|
||||
System.out.println("compare: "+
|
||||
((System.identityHashCode(this) <
|
||||
System.identityHashCode(other))
|
||||
? this+" to "+other
|
||||
: other+" to "+this)+
|
||||
" == "+ret+" at "+yrange[1]+
|
||||
" in "+(end-start)+"ms");
|
||||
*/
|
||||
lastEdge = other;
|
||||
lastLimit = yrange[1];
|
||||
lastResult = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void record(double yend, int etag) {
|
||||
this.activey = yend;
|
||||
this.etag = etag;
|
||||
}
|
||||
|
||||
public boolean isActiveFor(double y, int etag) {
|
||||
return (this.etag == etag && this.activey >= y);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return ("Edge["+curve+
|
||||
", "+
|
||||
(ctag == AreaOp.CTAG_LEFT ? "L" : "R")+
|
||||
", "+
|
||||
(etag == AreaOp.ETAG_ENTER ? "I" :
|
||||
(etag == AreaOp.ETAG_EXIT ? "O" : "N"))+
|
||||
"]");
|
||||
}
|
||||
}
|
||||
142
jdkSrc/jdk8/sun/awt/geom/Order0.java
Normal file
142
jdkSrc/jdk8/sun/awt/geom/Order0.java
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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.geom;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.util.Vector;
|
||||
|
||||
final class Order0 extends Curve {
|
||||
private double x;
|
||||
private double y;
|
||||
|
||||
public Order0(double x, double y) {
|
||||
super(INCREASING);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getXTop() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getYTop() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double getXBot() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getYBot() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double getXMin() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getXMax() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getX0() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getY0() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double getX1() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getY1() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double XforY(double y) {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double TforY(double y) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double XforT(double t) {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double YforT(double t) {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double dXforT(double t, int deriv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double dYforT(double t, int deriv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double nextVertical(double t0, double t1) {
|
||||
return t1;
|
||||
}
|
||||
|
||||
public int crossingsFor(double x, double y) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean accumulateCrossings(Crossings c) {
|
||||
return (x > c.getXLo() &&
|
||||
x < c.getXHi() &&
|
||||
y > c.getYLo() &&
|
||||
y < c.getYHi());
|
||||
}
|
||||
|
||||
public void enlarge(Rectangle2D r) {
|
||||
r.add(x, y);
|
||||
}
|
||||
|
||||
public Curve getSubCurve(double ystart, double yend, int dir) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Curve getReversedCurve() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getSegment(double coords[]) {
|
||||
coords[0] = x;
|
||||
coords[1] = y;
|
||||
return PathIterator.SEG_MOVETO;
|
||||
}
|
||||
}
|
||||
312
jdkSrc/jdk8/sun/awt/geom/Order1.java
Normal file
312
jdkSrc/jdk8/sun/awt/geom/Order1.java
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2006, 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.geom;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.util.Vector;
|
||||
|
||||
final class Order1 extends Curve {
|
||||
private double x0;
|
||||
private double y0;
|
||||
private double x1;
|
||||
private double y1;
|
||||
private double xmin;
|
||||
private double xmax;
|
||||
|
||||
public Order1(double x0, double y0,
|
||||
double x1, double y1,
|
||||
int direction)
|
||||
{
|
||||
super(direction);
|
||||
this.x0 = x0;
|
||||
this.y0 = y0;
|
||||
this.x1 = x1;
|
||||
this.y1 = y1;
|
||||
if (x0 < x1) {
|
||||
this.xmin = x0;
|
||||
this.xmax = x1;
|
||||
} else {
|
||||
this.xmin = x1;
|
||||
this.xmax = x0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public double getXTop() {
|
||||
return x0;
|
||||
}
|
||||
|
||||
public double getYTop() {
|
||||
return y0;
|
||||
}
|
||||
|
||||
public double getXBot() {
|
||||
return x1;
|
||||
}
|
||||
|
||||
public double getYBot() {
|
||||
return y1;
|
||||
}
|
||||
|
||||
public double getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
public double getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
public double getX0() {
|
||||
return (direction == INCREASING) ? x0 : x1;
|
||||
}
|
||||
|
||||
public double getY0() {
|
||||
return (direction == INCREASING) ? y0 : y1;
|
||||
}
|
||||
|
||||
public double getX1() {
|
||||
return (direction == DECREASING) ? x0 : x1;
|
||||
}
|
||||
|
||||
public double getY1() {
|
||||
return (direction == DECREASING) ? y0 : y1;
|
||||
}
|
||||
|
||||
public double XforY(double y) {
|
||||
if (x0 == x1 || y <= y0) {
|
||||
return x0;
|
||||
}
|
||||
if (y >= y1) {
|
||||
return x1;
|
||||
}
|
||||
// assert(y0 != y1); /* No horizontal lines... */
|
||||
return (x0 + (y - y0) * (x1 - x0) / (y1 - y0));
|
||||
}
|
||||
|
||||
public double TforY(double y) {
|
||||
if (y <= y0) {
|
||||
return 0;
|
||||
}
|
||||
if (y >= y1) {
|
||||
return 1;
|
||||
}
|
||||
return (y - y0) / (y1 - y0);
|
||||
}
|
||||
|
||||
public double XforT(double t) {
|
||||
return x0 + t * (x1 - x0);
|
||||
}
|
||||
|
||||
public double YforT(double t) {
|
||||
return y0 + t * (y1 - y0);
|
||||
}
|
||||
|
||||
public double dXforT(double t, int deriv) {
|
||||
switch (deriv) {
|
||||
case 0:
|
||||
return x0 + t * (x1 - x0);
|
||||
case 1:
|
||||
return (x1 - x0);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double dYforT(double t, int deriv) {
|
||||
switch (deriv) {
|
||||
case 0:
|
||||
return y0 + t * (y1 - y0);
|
||||
case 1:
|
||||
return (y1 - y0);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double nextVertical(double t0, double t1) {
|
||||
return t1;
|
||||
}
|
||||
|
||||
public boolean accumulateCrossings(Crossings c) {
|
||||
double xlo = c.getXLo();
|
||||
double ylo = c.getYLo();
|
||||
double xhi = c.getXHi();
|
||||
double yhi = c.getYHi();
|
||||
if (xmin >= xhi) {
|
||||
return false;
|
||||
}
|
||||
double xstart, ystart, xend, yend;
|
||||
if (y0 < ylo) {
|
||||
if (y1 <= ylo) {
|
||||
return false;
|
||||
}
|
||||
ystart = ylo;
|
||||
xstart = XforY(ylo);
|
||||
} else {
|
||||
if (y0 >= yhi) {
|
||||
return false;
|
||||
}
|
||||
ystart = y0;
|
||||
xstart = x0;
|
||||
}
|
||||
if (y1 > yhi) {
|
||||
yend = yhi;
|
||||
xend = XforY(yhi);
|
||||
} else {
|
||||
yend = y1;
|
||||
xend = x1;
|
||||
}
|
||||
if (xstart >= xhi && xend >= xhi) {
|
||||
return false;
|
||||
}
|
||||
if (xstart > xlo || xend > xlo) {
|
||||
return true;
|
||||
}
|
||||
c.record(ystart, yend, direction);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void enlarge(Rectangle2D r) {
|
||||
r.add(x0, y0);
|
||||
r.add(x1, y1);
|
||||
}
|
||||
|
||||
public Curve getSubCurve(double ystart, double yend, int dir) {
|
||||
if (ystart == y0 && yend == y1) {
|
||||
return getWithDirection(dir);
|
||||
}
|
||||
if (x0 == x1) {
|
||||
return new Order1(x0, ystart, x1, yend, dir);
|
||||
}
|
||||
double num = x0 - x1;
|
||||
double denom = y0 - y1;
|
||||
double xstart = (x0 + (ystart - y0) * num / denom);
|
||||
double xend = (x0 + (yend - y0) * num / denom);
|
||||
return new Order1(xstart, ystart, xend, yend, dir);
|
||||
}
|
||||
|
||||
public Curve getReversedCurve() {
|
||||
return new Order1(x0, y0, x1, y1, -direction);
|
||||
}
|
||||
|
||||
public int compareTo(Curve other, double yrange[]) {
|
||||
if (!(other instanceof Order1)) {
|
||||
return super.compareTo(other, yrange);
|
||||
}
|
||||
Order1 c1 = (Order1) other;
|
||||
if (yrange[1] <= yrange[0]) {
|
||||
throw new InternalError("yrange already screwed up...");
|
||||
}
|
||||
yrange[1] = Math.min(Math.min(yrange[1], y1), c1.y1);
|
||||
if (yrange[1] <= yrange[0]) {
|
||||
throw new InternalError("backstepping from "+yrange[0]+" to "+yrange[1]);
|
||||
}
|
||||
if (xmax <= c1.xmin) {
|
||||
return (xmin == c1.xmax) ? 0 : -1;
|
||||
}
|
||||
if (xmin >= c1.xmax) {
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* If "this" is curve A and "other" is curve B, then...
|
||||
* xA(y) = x0A + (y - y0A) (x1A - x0A) / (y1A - y0A)
|
||||
* xB(y) = x0B + (y - y0B) (x1B - x0B) / (y1B - y0B)
|
||||
* xA(y) == xB(y)
|
||||
* x0A + (y - y0A) (x1A - x0A) / (y1A - y0A)
|
||||
* == x0B + (y - y0B) (x1B - x0B) / (y1B - y0B)
|
||||
* 0 == x0A (y1A - y0A) (y1B - y0B) + (y - y0A) (x1A - x0A) (y1B - y0B)
|
||||
* - x0B (y1A - y0A) (y1B - y0B) - (y - y0B) (x1B - x0B) (y1A - y0A)
|
||||
* 0 == (x0A - x0B) (y1A - y0A) (y1B - y0B)
|
||||
* + (y - y0A) (x1A - x0A) (y1B - y0B)
|
||||
* - (y - y0B) (x1B - x0B) (y1A - y0A)
|
||||
* If (dxA == x1A - x0A), etc...
|
||||
* 0 == (x0A - x0B) * dyA * dyB
|
||||
* + (y - y0A) * dxA * dyB
|
||||
* - (y - y0B) * dxB * dyA
|
||||
* 0 == (x0A - x0B) * dyA * dyB
|
||||
* + y * dxA * dyB - y0A * dxA * dyB
|
||||
* - y * dxB * dyA + y0B * dxB * dyA
|
||||
* 0 == (x0A - x0B) * dyA * dyB
|
||||
* + y * dxA * dyB - y * dxB * dyA
|
||||
* - y0A * dxA * dyB + y0B * dxB * dyA
|
||||
* 0 == (x0A - x0B) * dyA * dyB
|
||||
* + y * (dxA * dyB - dxB * dyA)
|
||||
* - y0A * dxA * dyB + y0B * dxB * dyA
|
||||
* y == ((x0A - x0B) * dyA * dyB
|
||||
* - y0A * dxA * dyB + y0B * dxB * dyA)
|
||||
* / (-(dxA * dyB - dxB * dyA))
|
||||
* y == ((x0A - x0B) * dyA * dyB
|
||||
* - y0A * dxA * dyB + y0B * dxB * dyA)
|
||||
* / (dxB * dyA - dxA * dyB)
|
||||
*/
|
||||
double dxa = x1 - x0;
|
||||
double dya = y1 - y0;
|
||||
double dxb = c1.x1 - c1.x0;
|
||||
double dyb = c1.y1 - c1.y0;
|
||||
double denom = dxb * dya - dxa * dyb;
|
||||
double y;
|
||||
if (denom != 0) {
|
||||
double num = ((x0 - c1.x0) * dya * dyb
|
||||
- y0 * dxa * dyb
|
||||
+ c1.y0 * dxb * dya);
|
||||
y = num / denom;
|
||||
if (y <= yrange[0]) {
|
||||
// intersection is above us
|
||||
// Use bottom-most common y for comparison
|
||||
y = Math.min(y1, c1.y1);
|
||||
} else {
|
||||
// intersection is below the top of our range
|
||||
if (y < yrange[1]) {
|
||||
// If intersection is in our range, adjust valid range
|
||||
yrange[1] = y;
|
||||
}
|
||||
// Use top-most common y for comparison
|
||||
y = Math.max(y0, c1.y0);
|
||||
}
|
||||
} else {
|
||||
// lines are parallel, choose any common y for comparison
|
||||
// Note - prefer an endpoint for speed of calculating the X
|
||||
// (see shortcuts in Order1.XforY())
|
||||
y = Math.max(y0, c1.y0);
|
||||
}
|
||||
return orderof(XforY(y), c1.XforY(y));
|
||||
}
|
||||
|
||||
public int getSegment(double coords[]) {
|
||||
if (direction == INCREASING) {
|
||||
coords[0] = x1;
|
||||
coords[1] = y1;
|
||||
} else {
|
||||
coords[0] = x0;
|
||||
coords[1] = y0;
|
||||
}
|
||||
return PathIterator.SEG_LINETO;
|
||||
}
|
||||
}
|
||||
453
jdkSrc/jdk8/sun/awt/geom/Order2.java
Normal file
453
jdkSrc/jdk8/sun/awt/geom/Order2.java
Normal file
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2006, 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.geom;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.QuadCurve2D;
|
||||
import java.util.Vector;
|
||||
|
||||
final class Order2 extends Curve {
|
||||
private double x0;
|
||||
private double y0;
|
||||
private double cx0;
|
||||
private double cy0;
|
||||
private double x1;
|
||||
private double y1;
|
||||
private double xmin;
|
||||
private double xmax;
|
||||
|
||||
private double xcoeff0;
|
||||
private double xcoeff1;
|
||||
private double xcoeff2;
|
||||
private double ycoeff0;
|
||||
private double ycoeff1;
|
||||
private double ycoeff2;
|
||||
|
||||
public static void insert(Vector curves, double tmp[],
|
||||
double x0, double y0,
|
||||
double cx0, double cy0,
|
||||
double x1, double y1,
|
||||
int direction)
|
||||
{
|
||||
int numparams = getHorizontalParams(y0, cy0, y1, tmp);
|
||||
if (numparams == 0) {
|
||||
// We are using addInstance here to avoid inserting horisontal
|
||||
// segments
|
||||
addInstance(curves, x0, y0, cx0, cy0, x1, y1, direction);
|
||||
return;
|
||||
}
|
||||
// assert(numparams == 1);
|
||||
double t = tmp[0];
|
||||
tmp[0] = x0; tmp[1] = y0;
|
||||
tmp[2] = cx0; tmp[3] = cy0;
|
||||
tmp[4] = x1; tmp[5] = y1;
|
||||
split(tmp, 0, t);
|
||||
int i0 = (direction == INCREASING)? 0 : 4;
|
||||
int i1 = 4 - i0;
|
||||
addInstance(curves, tmp[i0], tmp[i0 + 1], tmp[i0 + 2], tmp[i0 + 3],
|
||||
tmp[i0 + 4], tmp[i0 + 5], direction);
|
||||
addInstance(curves, tmp[i1], tmp[i1 + 1], tmp[i1 + 2], tmp[i1 + 3],
|
||||
tmp[i1 + 4], tmp[i1 + 5], direction);
|
||||
}
|
||||
|
||||
public static void addInstance(Vector curves,
|
||||
double x0, double y0,
|
||||
double cx0, double cy0,
|
||||
double x1, double y1,
|
||||
int direction) {
|
||||
if (y0 > y1) {
|
||||
curves.add(new Order2(x1, y1, cx0, cy0, x0, y0, -direction));
|
||||
} else if (y1 > y0) {
|
||||
curves.add(new Order2(x0, y0, cx0, cy0, x1, y1, direction));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the count of the number of horizontal sections of the
|
||||
* specified quadratic Bezier curve. Put the parameters for the
|
||||
* horizontal sections into the specified <code>ret</code> array.
|
||||
* <p>
|
||||
* If we examine the parametric equation in t, we have:
|
||||
* Py(t) = C0*(1-t)^2 + 2*CP*t*(1-t) + C1*t^2
|
||||
* = C0 - 2*C0*t + C0*t^2 + 2*CP*t - 2*CP*t^2 + C1*t^2
|
||||
* = C0 + (2*CP - 2*C0)*t + (C0 - 2*CP + C1)*t^2
|
||||
* Py(t) = (C0 - 2*CP + C1)*t^2 + (2*CP - 2*C0)*t + (C0)
|
||||
* If we take the derivative, we get:
|
||||
* Py(t) = At^2 + Bt + C
|
||||
* dPy(t) = 2At + B = 0
|
||||
* 2*(C0 - 2*CP + C1)t + 2*(CP - C0) = 0
|
||||
* 2*(C0 - 2*CP + C1)t = 2*(C0 - CP)
|
||||
* t = 2*(C0 - CP) / 2*(C0 - 2*CP + C1)
|
||||
* t = (C0 - CP) / (C0 - CP + C1 - CP)
|
||||
* Note that this method will return 0 if the equation is a line,
|
||||
* which is either always horizontal or never horizontal.
|
||||
* Completely horizontal curves need to be eliminated by other
|
||||
* means outside of this method.
|
||||
*/
|
||||
public static int getHorizontalParams(double c0, double cp, double c1,
|
||||
double ret[]) {
|
||||
if (c0 <= cp && cp <= c1) {
|
||||
return 0;
|
||||
}
|
||||
c0 -= cp;
|
||||
c1 -= cp;
|
||||
double denom = c0 + c1;
|
||||
// If denom == 0 then cp == (c0+c1)/2 and we have a line.
|
||||
if (denom == 0) {
|
||||
return 0;
|
||||
}
|
||||
double t = c0 / denom;
|
||||
// No splits at t==0 and t==1
|
||||
if (t <= 0 || t >= 1) {
|
||||
return 0;
|
||||
}
|
||||
ret[0] = t;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Split the quadratic Bezier stored at coords[pos...pos+5] representing
|
||||
* the paramtric range [0..1] into two subcurves representing the
|
||||
* parametric subranges [0..t] and [t..1]. Store the results back
|
||||
* into the array at coords[pos...pos+5] and coords[pos+4...pos+9].
|
||||
*/
|
||||
public static void split(double coords[], int pos, double t) {
|
||||
double x0, y0, cx, cy, x1, y1;
|
||||
coords[pos+8] = x1 = coords[pos+4];
|
||||
coords[pos+9] = y1 = coords[pos+5];
|
||||
cx = coords[pos+2];
|
||||
cy = coords[pos+3];
|
||||
x1 = cx + (x1 - cx) * t;
|
||||
y1 = cy + (y1 - cy) * t;
|
||||
x0 = coords[pos+0];
|
||||
y0 = coords[pos+1];
|
||||
x0 = x0 + (cx - x0) * t;
|
||||
y0 = y0 + (cy - y0) * t;
|
||||
cx = x0 + (x1 - x0) * t;
|
||||
cy = y0 + (y1 - y0) * t;
|
||||
coords[pos+2] = x0;
|
||||
coords[pos+3] = y0;
|
||||
coords[pos+4] = cx;
|
||||
coords[pos+5] = cy;
|
||||
coords[pos+6] = x1;
|
||||
coords[pos+7] = y1;
|
||||
}
|
||||
|
||||
public Order2(double x0, double y0,
|
||||
double cx0, double cy0,
|
||||
double x1, double y1,
|
||||
int direction)
|
||||
{
|
||||
super(direction);
|
||||
// REMIND: Better accuracy in the root finding methods would
|
||||
// ensure that cy0 is in range. As it stands, it is never
|
||||
// more than "1 mantissa bit" out of range...
|
||||
if (cy0 < y0) {
|
||||
cy0 = y0;
|
||||
} else if (cy0 > y1) {
|
||||
cy0 = y1;
|
||||
}
|
||||
this.x0 = x0;
|
||||
this.y0 = y0;
|
||||
this.cx0 = cx0;
|
||||
this.cy0 = cy0;
|
||||
this.x1 = x1;
|
||||
this.y1 = y1;
|
||||
xmin = Math.min(Math.min(x0, x1), cx0);
|
||||
xmax = Math.max(Math.max(x0, x1), cx0);
|
||||
xcoeff0 = x0;
|
||||
xcoeff1 = cx0 + cx0 - x0 - x0;
|
||||
xcoeff2 = x0 - cx0 - cx0 + x1;
|
||||
ycoeff0 = y0;
|
||||
ycoeff1 = cy0 + cy0 - y0 - y0;
|
||||
ycoeff2 = y0 - cy0 - cy0 + y1;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public double getXTop() {
|
||||
return x0;
|
||||
}
|
||||
|
||||
public double getYTop() {
|
||||
return y0;
|
||||
}
|
||||
|
||||
public double getXBot() {
|
||||
return x1;
|
||||
}
|
||||
|
||||
public double getYBot() {
|
||||
return y1;
|
||||
}
|
||||
|
||||
public double getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
public double getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
public double getX0() {
|
||||
return (direction == INCREASING) ? x0 : x1;
|
||||
}
|
||||
|
||||
public double getY0() {
|
||||
return (direction == INCREASING) ? y0 : y1;
|
||||
}
|
||||
|
||||
public double getCX0() {
|
||||
return cx0;
|
||||
}
|
||||
|
||||
public double getCY0() {
|
||||
return cy0;
|
||||
}
|
||||
|
||||
public double getX1() {
|
||||
return (direction == DECREASING) ? x0 : x1;
|
||||
}
|
||||
|
||||
public double getY1() {
|
||||
return (direction == DECREASING) ? y0 : y1;
|
||||
}
|
||||
|
||||
public double XforY(double y) {
|
||||
if (y <= y0) {
|
||||
return x0;
|
||||
}
|
||||
if (y >= y1) {
|
||||
return x1;
|
||||
}
|
||||
return XforT(TforY(y));
|
||||
}
|
||||
|
||||
public double TforY(double y) {
|
||||
if (y <= y0) {
|
||||
return 0;
|
||||
}
|
||||
if (y >= y1) {
|
||||
return 1;
|
||||
}
|
||||
return TforY(y, ycoeff0, ycoeff1, ycoeff2);
|
||||
}
|
||||
|
||||
public static double TforY(double y,
|
||||
double ycoeff0, double ycoeff1, double ycoeff2)
|
||||
{
|
||||
// The caller should have already eliminated y values
|
||||
// outside of the y0 to y1 range.
|
||||
ycoeff0 -= y;
|
||||
if (ycoeff2 == 0.0) {
|
||||
// The quadratic parabola has degenerated to a line.
|
||||
// ycoeff1 should not be 0.0 since we have already eliminated
|
||||
// totally horizontal lines, but if it is, then we will generate
|
||||
// infinity here for the root, which will not be in the [0,1]
|
||||
// range so we will pass to the failure code below.
|
||||
double root = -ycoeff0 / ycoeff1;
|
||||
if (root >= 0 && root <= 1) {
|
||||
return root;
|
||||
}
|
||||
} else {
|
||||
// From Numerical Recipes, 5.6, Quadratic and Cubic Equations
|
||||
double d = ycoeff1 * ycoeff1 - 4.0 * ycoeff2 * ycoeff0;
|
||||
// If d < 0.0, then there are no roots
|
||||
if (d >= 0.0) {
|
||||
d = Math.sqrt(d);
|
||||
// For accuracy, calculate one root using:
|
||||
// (-ycoeff1 +/- d) / 2ycoeff2
|
||||
// and the other using:
|
||||
// 2ycoeff0 / (-ycoeff1 +/- d)
|
||||
// Choose the sign of the +/- so that ycoeff1+d
|
||||
// gets larger in magnitude
|
||||
if (ycoeff1 < 0.0) {
|
||||
d = -d;
|
||||
}
|
||||
double q = (ycoeff1 + d) / -2.0;
|
||||
// We already tested ycoeff2 for being 0 above
|
||||
double root = q / ycoeff2;
|
||||
if (root >= 0 && root <= 1) {
|
||||
return root;
|
||||
}
|
||||
if (q != 0.0) {
|
||||
root = ycoeff0 / q;
|
||||
if (root >= 0 && root <= 1) {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* We failed to find a root in [0,1]. What could have gone wrong?
|
||||
* First, remember that these curves are constructed to be monotonic
|
||||
* in Y and totally horizontal curves have already been eliminated.
|
||||
* Now keep in mind that the Y coefficients of the polynomial form
|
||||
* of the curve are calculated from the Y coordinates which define
|
||||
* our curve. They should theoretically define the same curve,
|
||||
* but they can be off by a couple of bits of precision after the
|
||||
* math is done and so can represent a slightly modified curve.
|
||||
* This is normally not an issue except when we have solutions near
|
||||
* the endpoints. Since the answers we get from solving the polynomial
|
||||
* may be off by a few bits that means that they could lie just a
|
||||
* few bits of precision outside the [0,1] range.
|
||||
*
|
||||
* Another problem could be that while the parametric curve defined
|
||||
* by the Y coordinates has a local minima or maxima at or just
|
||||
* outside of the endpoints, the polynomial form might express
|
||||
* that same min/max just inside of and just shy of the Y coordinate
|
||||
* of that endpoint. In that case, if we solve for a Y coordinate
|
||||
* at or near that endpoint, we may be solving for a Y coordinate
|
||||
* that is below that minima or above that maxima and we would find
|
||||
* no solutions at all.
|
||||
*
|
||||
* In either case, we can assume that y is so near one of the
|
||||
* endpoints that we can just collapse it onto the nearest endpoint
|
||||
* without losing more than a couple of bits of precision.
|
||||
*/
|
||||
// First calculate the midpoint between y0 and y1 and choose to
|
||||
// return either 0.0 or 1.0 depending on whether y is above
|
||||
// or below the midpoint...
|
||||
// Note that we subtracted y from ycoeff0 above so both y0 and y1
|
||||
// will be "relative to y" so we are really just looking at where
|
||||
// zero falls with respect to the "relative midpoint" here.
|
||||
double y0 = ycoeff0;
|
||||
double y1 = ycoeff0 + ycoeff1 + ycoeff2;
|
||||
return (0 < (y0 + y1) / 2) ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
public double XforT(double t) {
|
||||
return (xcoeff2 * t + xcoeff1) * t + xcoeff0;
|
||||
}
|
||||
|
||||
public double YforT(double t) {
|
||||
return (ycoeff2 * t + ycoeff1) * t + ycoeff0;
|
||||
}
|
||||
|
||||
public double dXforT(double t, int deriv) {
|
||||
switch (deriv) {
|
||||
case 0:
|
||||
return (xcoeff2 * t + xcoeff1) * t + xcoeff0;
|
||||
case 1:
|
||||
return 2 * xcoeff2 * t + xcoeff1;
|
||||
case 2:
|
||||
return 2 * xcoeff2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double dYforT(double t, int deriv) {
|
||||
switch (deriv) {
|
||||
case 0:
|
||||
return (ycoeff2 * t + ycoeff1) * t + ycoeff0;
|
||||
case 1:
|
||||
return 2 * ycoeff2 * t + ycoeff1;
|
||||
case 2:
|
||||
return 2 * ycoeff2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double nextVertical(double t0, double t1) {
|
||||
double t = -xcoeff1 / (2 * xcoeff2);
|
||||
if (t > t0 && t < t1) {
|
||||
return t;
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
public void enlarge(Rectangle2D r) {
|
||||
r.add(x0, y0);
|
||||
double t = -xcoeff1 / (2 * xcoeff2);
|
||||
if (t > 0 && t < 1) {
|
||||
r.add(XforT(t), YforT(t));
|
||||
}
|
||||
r.add(x1, y1);
|
||||
}
|
||||
|
||||
public Curve getSubCurve(double ystart, double yend, int dir) {
|
||||
double t0, t1;
|
||||
if (ystart <= y0) {
|
||||
if (yend >= y1) {
|
||||
return getWithDirection(dir);
|
||||
}
|
||||
t0 = 0;
|
||||
} else {
|
||||
t0 = TforY(ystart, ycoeff0, ycoeff1, ycoeff2);
|
||||
}
|
||||
if (yend >= y1) {
|
||||
t1 = 1;
|
||||
} else {
|
||||
t1 = TforY(yend, ycoeff0, ycoeff1, ycoeff2);
|
||||
}
|
||||
double eqn[] = new double[10];
|
||||
eqn[0] = x0;
|
||||
eqn[1] = y0;
|
||||
eqn[2] = cx0;
|
||||
eqn[3] = cy0;
|
||||
eqn[4] = x1;
|
||||
eqn[5] = y1;
|
||||
if (t1 < 1) {
|
||||
split(eqn, 0, t1);
|
||||
}
|
||||
int i;
|
||||
if (t0 <= 0) {
|
||||
i = 0;
|
||||
} else {
|
||||
split(eqn, 0, t0 / t1);
|
||||
i = 4;
|
||||
}
|
||||
return new Order2(eqn[i+0], ystart,
|
||||
eqn[i+2], eqn[i+3],
|
||||
eqn[i+4], yend,
|
||||
dir);
|
||||
}
|
||||
|
||||
public Curve getReversedCurve() {
|
||||
return new Order2(x0, y0, cx0, cy0, x1, y1, -direction);
|
||||
}
|
||||
|
||||
public int getSegment(double coords[]) {
|
||||
coords[0] = cx0;
|
||||
coords[1] = cy0;
|
||||
if (direction == INCREASING) {
|
||||
coords[2] = x1;
|
||||
coords[3] = y1;
|
||||
} else {
|
||||
coords[2] = x0;
|
||||
coords[3] = y0;
|
||||
}
|
||||
return PathIterator.SEG_QUADTO;
|
||||
}
|
||||
|
||||
public String controlPointString() {
|
||||
return ("("+round(cx0)+", "+round(cy0)+"), ");
|
||||
}
|
||||
}
|
||||
634
jdkSrc/jdk8/sun/awt/geom/Order3.java
Normal file
634
jdkSrc/jdk8/sun/awt/geom/Order3.java
Normal file
@@ -0,0 +1,634 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2006, 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.geom;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.QuadCurve2D;
|
||||
import java.util.Vector;
|
||||
|
||||
final class Order3 extends Curve {
|
||||
private double x0;
|
||||
private double y0;
|
||||
private double cx0;
|
||||
private double cy0;
|
||||
private double cx1;
|
||||
private double cy1;
|
||||
private double x1;
|
||||
private double y1;
|
||||
|
||||
private double xmin;
|
||||
private double xmax;
|
||||
|
||||
private double xcoeff0;
|
||||
private double xcoeff1;
|
||||
private double xcoeff2;
|
||||
private double xcoeff3;
|
||||
|
||||
private double ycoeff0;
|
||||
private double ycoeff1;
|
||||
private double ycoeff2;
|
||||
private double ycoeff3;
|
||||
|
||||
public static void insert(Vector curves, double tmp[],
|
||||
double x0, double y0,
|
||||
double cx0, double cy0,
|
||||
double cx1, double cy1,
|
||||
double x1, double y1,
|
||||
int direction)
|
||||
{
|
||||
int numparams = getHorizontalParams(y0, cy0, cy1, y1, tmp);
|
||||
if (numparams == 0) {
|
||||
// We are using addInstance here to avoid inserting horisontal
|
||||
// segments
|
||||
addInstance(curves, x0, y0, cx0, cy0, cx1, cy1, x1, y1, direction);
|
||||
return;
|
||||
}
|
||||
// Store coordinates for splitting at tmp[3..10]
|
||||
tmp[3] = x0; tmp[4] = y0;
|
||||
tmp[5] = cx0; tmp[6] = cy0;
|
||||
tmp[7] = cx1; tmp[8] = cy1;
|
||||
tmp[9] = x1; tmp[10] = y1;
|
||||
double t = tmp[0];
|
||||
if (numparams > 1 && t > tmp[1]) {
|
||||
// Perform a "2 element sort"...
|
||||
tmp[0] = tmp[1];
|
||||
tmp[1] = t;
|
||||
t = tmp[0];
|
||||
}
|
||||
split(tmp, 3, t);
|
||||
if (numparams > 1) {
|
||||
// Recalculate tmp[1] relative to the range [tmp[0]...1]
|
||||
t = (tmp[1] - t) / (1 - t);
|
||||
split(tmp, 9, t);
|
||||
}
|
||||
int index = 3;
|
||||
if (direction == DECREASING) {
|
||||
index += numparams * 6;
|
||||
}
|
||||
while (numparams >= 0) {
|
||||
addInstance(curves,
|
||||
tmp[index + 0], tmp[index + 1],
|
||||
tmp[index + 2], tmp[index + 3],
|
||||
tmp[index + 4], tmp[index + 5],
|
||||
tmp[index + 6], tmp[index + 7],
|
||||
direction);
|
||||
numparams--;
|
||||
if (direction == INCREASING) {
|
||||
index += 6;
|
||||
} else {
|
||||
index -= 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addInstance(Vector curves,
|
||||
double x0, double y0,
|
||||
double cx0, double cy0,
|
||||
double cx1, double cy1,
|
||||
double x1, double y1,
|
||||
int direction) {
|
||||
if (y0 > y1) {
|
||||
curves.add(new Order3(x1, y1, cx1, cy1, cx0, cy0, x0, y0,
|
||||
-direction));
|
||||
} else if (y1 > y0) {
|
||||
curves.add(new Order3(x0, y0, cx0, cy0, cx1, cy1, x1, y1,
|
||||
direction));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the count of the number of horizontal sections of the
|
||||
* specified cubic Bezier curve. Put the parameters for the
|
||||
* horizontal sections into the specified <code>ret</code> array.
|
||||
* <p>
|
||||
* If we examine the parametric equation in t, we have:
|
||||
* Py(t) = C0(1-t)^3 + 3CP0 t(1-t)^2 + 3CP1 t^2(1-t) + C1 t^3
|
||||
* = C0 - 3C0t + 3C0t^2 - C0t^3 +
|
||||
* 3CP0t - 6CP0t^2 + 3CP0t^3 +
|
||||
* 3CP1t^2 - 3CP1t^3 +
|
||||
* C1t^3
|
||||
* Py(t) = (C1 - 3CP1 + 3CP0 - C0) t^3 +
|
||||
* (3C0 - 6CP0 + 3CP1) t^2 +
|
||||
* (3CP0 - 3C0) t +
|
||||
* (C0)
|
||||
* If we take the derivative, we get:
|
||||
* Py(t) = Dt^3 + At^2 + Bt + C
|
||||
* dPy(t) = 3Dt^2 + 2At + B = 0
|
||||
* 0 = 3*(C1 - 3*CP1 + 3*CP0 - C0)t^2
|
||||
* + 2*(3*CP1 - 6*CP0 + 3*C0)t
|
||||
* + (3*CP0 - 3*C0)
|
||||
* 0 = 3*(C1 - 3*CP1 + 3*CP0 - C0)t^2
|
||||
* + 3*2*(CP1 - 2*CP0 + C0)t
|
||||
* + 3*(CP0 - C0)
|
||||
* 0 = (C1 - CP1 - CP1 - CP1 + CP0 + CP0 + CP0 - C0)t^2
|
||||
* + 2*(CP1 - CP0 - CP0 + C0)t
|
||||
* + (CP0 - C0)
|
||||
* 0 = (C1 - CP1 + CP0 - CP1 + CP0 - CP1 + CP0 - C0)t^2
|
||||
* + 2*(CP1 - CP0 - CP0 + C0)t
|
||||
* + (CP0 - C0)
|
||||
* 0 = ((C1 - CP1) - (CP1 - CP0) - (CP1 - CP0) + (CP0 - C0))t^2
|
||||
* + 2*((CP1 - CP0) - (CP0 - C0))t
|
||||
* + (CP0 - C0)
|
||||
* Note that this method will return 0 if the equation is a line,
|
||||
* which is either always horizontal or never horizontal.
|
||||
* Completely horizontal curves need to be eliminated by other
|
||||
* means outside of this method.
|
||||
*/
|
||||
public static int getHorizontalParams(double c0, double cp0,
|
||||
double cp1, double c1,
|
||||
double ret[]) {
|
||||
if (c0 <= cp0 && cp0 <= cp1 && cp1 <= c1) {
|
||||
return 0;
|
||||
}
|
||||
c1 -= cp1;
|
||||
cp1 -= cp0;
|
||||
cp0 -= c0;
|
||||
ret[0] = cp0;
|
||||
ret[1] = (cp1 - cp0) * 2;
|
||||
ret[2] = (c1 - cp1 - cp1 + cp0);
|
||||
int numroots = QuadCurve2D.solveQuadratic(ret, ret);
|
||||
int j = 0;
|
||||
for (int i = 0; i < numroots; i++) {
|
||||
double t = ret[i];
|
||||
// No splits at t==0 and t==1
|
||||
if (t > 0 && t < 1) {
|
||||
if (j < i) {
|
||||
ret[j] = t;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
/*
|
||||
* Split the cubic Bezier stored at coords[pos...pos+7] representing
|
||||
* the parametric range [0..1] into two subcurves representing the
|
||||
* parametric subranges [0..t] and [t..1]. Store the results back
|
||||
* into the array at coords[pos...pos+7] and coords[pos+6...pos+13].
|
||||
*/
|
||||
public static void split(double coords[], int pos, double t) {
|
||||
double x0, y0, cx0, cy0, cx1, cy1, x1, y1;
|
||||
coords[pos+12] = x1 = coords[pos+6];
|
||||
coords[pos+13] = y1 = coords[pos+7];
|
||||
cx1 = coords[pos+4];
|
||||
cy1 = coords[pos+5];
|
||||
x1 = cx1 + (x1 - cx1) * t;
|
||||
y1 = cy1 + (y1 - cy1) * t;
|
||||
x0 = coords[pos+0];
|
||||
y0 = coords[pos+1];
|
||||
cx0 = coords[pos+2];
|
||||
cy0 = coords[pos+3];
|
||||
x0 = x0 + (cx0 - x0) * t;
|
||||
y0 = y0 + (cy0 - y0) * t;
|
||||
cx0 = cx0 + (cx1 - cx0) * t;
|
||||
cy0 = cy0 + (cy1 - cy0) * t;
|
||||
cx1 = cx0 + (x1 - cx0) * t;
|
||||
cy1 = cy0 + (y1 - cy0) * t;
|
||||
cx0 = x0 + (cx0 - x0) * t;
|
||||
cy0 = y0 + (cy0 - y0) * t;
|
||||
coords[pos+2] = x0;
|
||||
coords[pos+3] = y0;
|
||||
coords[pos+4] = cx0;
|
||||
coords[pos+5] = cy0;
|
||||
coords[pos+6] = cx0 + (cx1 - cx0) * t;
|
||||
coords[pos+7] = cy0 + (cy1 - cy0) * t;
|
||||
coords[pos+8] = cx1;
|
||||
coords[pos+9] = cy1;
|
||||
coords[pos+10] = x1;
|
||||
coords[pos+11] = y1;
|
||||
}
|
||||
|
||||
public Order3(double x0, double y0,
|
||||
double cx0, double cy0,
|
||||
double cx1, double cy1,
|
||||
double x1, double y1,
|
||||
int direction)
|
||||
{
|
||||
super(direction);
|
||||
// REMIND: Better accuracy in the root finding methods would
|
||||
// ensure that cys are in range. As it stands, they are never
|
||||
// more than "1 mantissa bit" out of range...
|
||||
if (cy0 < y0) cy0 = y0;
|
||||
if (cy1 > y1) cy1 = y1;
|
||||
this.x0 = x0;
|
||||
this.y0 = y0;
|
||||
this.cx0 = cx0;
|
||||
this.cy0 = cy0;
|
||||
this.cx1 = cx1;
|
||||
this.cy1 = cy1;
|
||||
this.x1 = x1;
|
||||
this.y1 = y1;
|
||||
xmin = Math.min(Math.min(x0, x1), Math.min(cx0, cx1));
|
||||
xmax = Math.max(Math.max(x0, x1), Math.max(cx0, cx1));
|
||||
xcoeff0 = x0;
|
||||
xcoeff1 = (cx0 - x0) * 3.0;
|
||||
xcoeff2 = (cx1 - cx0 - cx0 + x0) * 3.0;
|
||||
xcoeff3 = x1 - (cx1 - cx0) * 3.0 - x0;
|
||||
ycoeff0 = y0;
|
||||
ycoeff1 = (cy0 - y0) * 3.0;
|
||||
ycoeff2 = (cy1 - cy0 - cy0 + y0) * 3.0;
|
||||
ycoeff3 = y1 - (cy1 - cy0) * 3.0 - y0;
|
||||
YforT1 = YforT2 = YforT3 = y0;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public double getXTop() {
|
||||
return x0;
|
||||
}
|
||||
|
||||
public double getYTop() {
|
||||
return y0;
|
||||
}
|
||||
|
||||
public double getXBot() {
|
||||
return x1;
|
||||
}
|
||||
|
||||
public double getYBot() {
|
||||
return y1;
|
||||
}
|
||||
|
||||
public double getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
public double getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
public double getX0() {
|
||||
return (direction == INCREASING) ? x0 : x1;
|
||||
}
|
||||
|
||||
public double getY0() {
|
||||
return (direction == INCREASING) ? y0 : y1;
|
||||
}
|
||||
|
||||
public double getCX0() {
|
||||
return (direction == INCREASING) ? cx0 : cx1;
|
||||
}
|
||||
|
||||
public double getCY0() {
|
||||
return (direction == INCREASING) ? cy0 : cy1;
|
||||
}
|
||||
|
||||
public double getCX1() {
|
||||
return (direction == DECREASING) ? cx0 : cx1;
|
||||
}
|
||||
|
||||
public double getCY1() {
|
||||
return (direction == DECREASING) ? cy0 : cy1;
|
||||
}
|
||||
|
||||
public double getX1() {
|
||||
return (direction == DECREASING) ? x0 : x1;
|
||||
}
|
||||
|
||||
public double getY1() {
|
||||
return (direction == DECREASING) ? y0 : y1;
|
||||
}
|
||||
|
||||
private double TforY1;
|
||||
private double YforT1;
|
||||
private double TforY2;
|
||||
private double YforT2;
|
||||
private double TforY3;
|
||||
private double YforT3;
|
||||
|
||||
/*
|
||||
* Solve the cubic whose coefficients are in the a,b,c,d fields and
|
||||
* return the first root in the range [0, 1].
|
||||
* The cubic solved is represented by the equation:
|
||||
* x^3 + (ycoeff2)x^2 + (ycoeff1)x + (ycoeff0) = y
|
||||
* @return the first valid root (in the range [0, 1])
|
||||
*/
|
||||
public double TforY(double y) {
|
||||
if (y <= y0) return 0;
|
||||
if (y >= y1) return 1;
|
||||
if (y == YforT1) return TforY1;
|
||||
if (y == YforT2) return TforY2;
|
||||
if (y == YforT3) return TforY3;
|
||||
// From Numerical Recipes, 5.6, Quadratic and Cubic Equations
|
||||
if (ycoeff3 == 0.0) {
|
||||
// The cubic degenerated to quadratic (or line or ...).
|
||||
return Order2.TforY(y, ycoeff0, ycoeff1, ycoeff2);
|
||||
}
|
||||
double a = ycoeff2 / ycoeff3;
|
||||
double b = ycoeff1 / ycoeff3;
|
||||
double c = (ycoeff0 - y) / ycoeff3;
|
||||
int roots = 0;
|
||||
double Q = (a * a - 3.0 * b) / 9.0;
|
||||
double R = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;
|
||||
double R2 = R * R;
|
||||
double Q3 = Q * Q * Q;
|
||||
double a_3 = a / 3.0;
|
||||
double t;
|
||||
if (R2 < Q3) {
|
||||
double theta = Math.acos(R / Math.sqrt(Q3));
|
||||
Q = -2.0 * Math.sqrt(Q);
|
||||
t = refine(a, b, c, y, Q * Math.cos(theta / 3.0) - a_3);
|
||||
if (t < 0) {
|
||||
t = refine(a, b, c, y,
|
||||
Q * Math.cos((theta + Math.PI * 2.0)/ 3.0) - a_3);
|
||||
}
|
||||
if (t < 0) {
|
||||
t = refine(a, b, c, y,
|
||||
Q * Math.cos((theta - Math.PI * 2.0)/ 3.0) - a_3);
|
||||
}
|
||||
} else {
|
||||
boolean neg = (R < 0.0);
|
||||
double S = Math.sqrt(R2 - Q3);
|
||||
if (neg) {
|
||||
R = -R;
|
||||
}
|
||||
double A = Math.pow(R + S, 1.0 / 3.0);
|
||||
if (!neg) {
|
||||
A = -A;
|
||||
}
|
||||
double B = (A == 0.0) ? 0.0 : (Q / A);
|
||||
t = refine(a, b, c, y, (A + B) - a_3);
|
||||
}
|
||||
if (t < 0) {
|
||||
//throw new InternalError("bad t");
|
||||
double t0 = 0;
|
||||
double t1 = 1;
|
||||
while (true) {
|
||||
t = (t0 + t1) / 2;
|
||||
if (t == t0 || t == t1) {
|
||||
break;
|
||||
}
|
||||
double yt = YforT(t);
|
||||
if (yt < y) {
|
||||
t0 = t;
|
||||
} else if (yt > y) {
|
||||
t1 = t;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (t >= 0) {
|
||||
TforY3 = TforY2;
|
||||
YforT3 = YforT2;
|
||||
TforY2 = TforY1;
|
||||
YforT2 = YforT1;
|
||||
TforY1 = t;
|
||||
YforT1 = y;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public double refine(double a, double b, double c,
|
||||
double target, double t)
|
||||
{
|
||||
if (t < -0.1 || t > 1.1) {
|
||||
return -1;
|
||||
}
|
||||
double y = YforT(t);
|
||||
double t0, t1;
|
||||
if (y < target) {
|
||||
t0 = t;
|
||||
t1 = 1;
|
||||
} else {
|
||||
t0 = 0;
|
||||
t1 = t;
|
||||
}
|
||||
double origt = t;
|
||||
double origy = y;
|
||||
boolean useslope = true;
|
||||
while (y != target) {
|
||||
if (!useslope) {
|
||||
double t2 = (t0 + t1) / 2;
|
||||
if (t2 == t0 || t2 == t1) {
|
||||
break;
|
||||
}
|
||||
t = t2;
|
||||
} else {
|
||||
double slope = dYforT(t, 1);
|
||||
if (slope == 0) {
|
||||
useslope = false;
|
||||
continue;
|
||||
}
|
||||
double t2 = t + ((target - y) / slope);
|
||||
if (t2 == t || t2 <= t0 || t2 >= t1) {
|
||||
useslope = false;
|
||||
continue;
|
||||
}
|
||||
t = t2;
|
||||
}
|
||||
y = YforT(t);
|
||||
if (y < target) {
|
||||
t0 = t;
|
||||
} else if (y > target) {
|
||||
t1 = t;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
boolean verbose = false;
|
||||
if (false && t >= 0 && t <= 1) {
|
||||
y = YforT(t);
|
||||
long tdiff = diffbits(t, origt);
|
||||
long ydiff = diffbits(y, origy);
|
||||
long yerr = diffbits(y, target);
|
||||
if (yerr > 0 || (verbose && tdiff > 0)) {
|
||||
System.out.println("target was y = "+target);
|
||||
System.out.println("original was y = "+origy+", t = "+origt);
|
||||
System.out.println("final was y = "+y+", t = "+t);
|
||||
System.out.println("t diff is "+tdiff);
|
||||
System.out.println("y diff is "+ydiff);
|
||||
System.out.println("y error is "+yerr);
|
||||
double tlow = prev(t);
|
||||
double ylow = YforT(tlow);
|
||||
double thi = next(t);
|
||||
double yhi = YforT(thi);
|
||||
if (Math.abs(target - ylow) < Math.abs(target - y) ||
|
||||
Math.abs(target - yhi) < Math.abs(target - y))
|
||||
{
|
||||
System.out.println("adjacent y's = ["+ylow+", "+yhi+"]");
|
||||
}
|
||||
}
|
||||
}
|
||||
return (t > 1) ? -1 : t;
|
||||
}
|
||||
|
||||
public double XforY(double y) {
|
||||
if (y <= y0) {
|
||||
return x0;
|
||||
}
|
||||
if (y >= y1) {
|
||||
return x1;
|
||||
}
|
||||
return XforT(TforY(y));
|
||||
}
|
||||
|
||||
public double XforT(double t) {
|
||||
return (((xcoeff3 * t) + xcoeff2) * t + xcoeff1) * t + xcoeff0;
|
||||
}
|
||||
|
||||
public double YforT(double t) {
|
||||
return (((ycoeff3 * t) + ycoeff2) * t + ycoeff1) * t + ycoeff0;
|
||||
}
|
||||
|
||||
public double dXforT(double t, int deriv) {
|
||||
switch (deriv) {
|
||||
case 0:
|
||||
return (((xcoeff3 * t) + xcoeff2) * t + xcoeff1) * t + xcoeff0;
|
||||
case 1:
|
||||
return ((3 * xcoeff3 * t) + 2 * xcoeff2) * t + xcoeff1;
|
||||
case 2:
|
||||
return (6 * xcoeff3 * t) + 2 * xcoeff2;
|
||||
case 3:
|
||||
return 6 * xcoeff3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double dYforT(double t, int deriv) {
|
||||
switch (deriv) {
|
||||
case 0:
|
||||
return (((ycoeff3 * t) + ycoeff2) * t + ycoeff1) * t + ycoeff0;
|
||||
case 1:
|
||||
return ((3 * ycoeff3 * t) + 2 * ycoeff2) * t + ycoeff1;
|
||||
case 2:
|
||||
return (6 * ycoeff3 * t) + 2 * ycoeff2;
|
||||
case 3:
|
||||
return 6 * ycoeff3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double nextVertical(double t0, double t1) {
|
||||
double eqn[] = {xcoeff1, 2 * xcoeff2, 3 * xcoeff3};
|
||||
int numroots = QuadCurve2D.solveQuadratic(eqn, eqn);
|
||||
for (int i = 0; i < numroots; i++) {
|
||||
if (eqn[i] > t0 && eqn[i] < t1) {
|
||||
t1 = eqn[i];
|
||||
}
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
public void enlarge(Rectangle2D r) {
|
||||
r.add(x0, y0);
|
||||
double eqn[] = {xcoeff1, 2 * xcoeff2, 3 * xcoeff3};
|
||||
int numroots = QuadCurve2D.solveQuadratic(eqn, eqn);
|
||||
for (int i = 0; i < numroots; i++) {
|
||||
double t = eqn[i];
|
||||
if (t > 0 && t < 1) {
|
||||
r.add(XforT(t), YforT(t));
|
||||
}
|
||||
}
|
||||
r.add(x1, y1);
|
||||
}
|
||||
|
||||
public Curve getSubCurve(double ystart, double yend, int dir) {
|
||||
if (ystart <= y0 && yend >= y1) {
|
||||
return getWithDirection(dir);
|
||||
}
|
||||
double eqn[] = new double[14];
|
||||
double t0, t1;
|
||||
t0 = TforY(ystart);
|
||||
t1 = TforY(yend);
|
||||
eqn[0] = x0;
|
||||
eqn[1] = y0;
|
||||
eqn[2] = cx0;
|
||||
eqn[3] = cy0;
|
||||
eqn[4] = cx1;
|
||||
eqn[5] = cy1;
|
||||
eqn[6] = x1;
|
||||
eqn[7] = y1;
|
||||
if (t0 > t1) {
|
||||
/* This happens in only rare cases where ystart is
|
||||
* very near yend and solving for the yend root ends
|
||||
* up stepping slightly lower in t than solving for
|
||||
* the ystart root.
|
||||
* Ideally we might want to skip this tiny little
|
||||
* segment and just fudge the surrounding coordinates
|
||||
* to bridge the gap left behind, but there is no way
|
||||
* to do that from here. Higher levels could
|
||||
* potentially eliminate these tiny "fixup" segments,
|
||||
* but not without a lot of extra work on the code that
|
||||
* coalesces chains of curves into subpaths. The
|
||||
* simplest solution for now is to just reorder the t
|
||||
* values and chop out a miniscule curve piece.
|
||||
*/
|
||||
double t = t0;
|
||||
t0 = t1;
|
||||
t1 = t;
|
||||
}
|
||||
if (t1 < 1) {
|
||||
split(eqn, 0, t1);
|
||||
}
|
||||
int i;
|
||||
if (t0 <= 0) {
|
||||
i = 0;
|
||||
} else {
|
||||
split(eqn, 0, t0 / t1);
|
||||
i = 6;
|
||||
}
|
||||
return new Order3(eqn[i+0], ystart,
|
||||
eqn[i+2], eqn[i+3],
|
||||
eqn[i+4], eqn[i+5],
|
||||
eqn[i+6], yend,
|
||||
dir);
|
||||
}
|
||||
|
||||
public Curve getReversedCurve() {
|
||||
return new Order3(x0, y0, cx0, cy0, cx1, cy1, x1, y1, -direction);
|
||||
}
|
||||
|
||||
public int getSegment(double coords[]) {
|
||||
if (direction == INCREASING) {
|
||||
coords[0] = cx0;
|
||||
coords[1] = cy0;
|
||||
coords[2] = cx1;
|
||||
coords[3] = cy1;
|
||||
coords[4] = x1;
|
||||
coords[5] = y1;
|
||||
} else {
|
||||
coords[0] = cx1;
|
||||
coords[1] = cy1;
|
||||
coords[2] = cx0;
|
||||
coords[3] = cy0;
|
||||
coords[4] = x0;
|
||||
coords[5] = y0;
|
||||
}
|
||||
return PathIterator.SEG_CUBICTO;
|
||||
}
|
||||
|
||||
public String controlPointString() {
|
||||
return (("("+round(getCX0())+", "+round(getCY0())+"), ")+
|
||||
("("+round(getCX1())+", "+round(getCY1())+"), "));
|
||||
}
|
||||
}
|
||||
78
jdkSrc/jdk8/sun/awt/geom/PathConsumer2D.java
Normal file
78
jdkSrc/jdk8/sun/awt/geom/PathConsumer2D.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.geom;
|
||||
|
||||
public interface PathConsumer2D {
|
||||
/**
|
||||
* @see java.awt.geom.Path2D.Float.moveTo
|
||||
*/
|
||||
public void moveTo(float x, float y);
|
||||
|
||||
/**
|
||||
* @see java.awt.geom.Path2D.Float.lineTo
|
||||
*/
|
||||
public void lineTo(float x, float y);
|
||||
|
||||
/**
|
||||
* @see java.awt.geom.Path2D.Float.quadTo
|
||||
*/
|
||||
public void quadTo(float x1, float y1,
|
||||
float x2, float y2);
|
||||
|
||||
/**
|
||||
* @see java.awt.geom.Path2D.Float.curveTo
|
||||
*/
|
||||
public void curveTo(float x1, float y1,
|
||||
float x2, float y2,
|
||||
float x3, float y3);
|
||||
|
||||
/**
|
||||
* @see java.awt.geom.Path2D.Float.closePath
|
||||
*/
|
||||
public void closePath();
|
||||
|
||||
/**
|
||||
* Called after the last segment of the last subpath when the
|
||||
* iteration of the path segments is completely done. This
|
||||
* method serves to trigger the end of path processing in the
|
||||
* consumer that would normally be triggered when a
|
||||
* {@link java.awt.geom.PathIterator PathIterator}
|
||||
* returns {@code true} from its {@code done} method.
|
||||
*/
|
||||
public void pathDone();
|
||||
|
||||
/**
|
||||
* If a given PathConsumer performs all or most of its work
|
||||
* natively then it can return a (non-zero) pointer to a
|
||||
* native function vector that defines C functions for all
|
||||
* of the above methods.
|
||||
* The specific pointer it returns is a pointer to a
|
||||
* PathConsumerVec structure as defined in the include file
|
||||
* src/share/native/sun/java2d/pipe/PathConsumer2D.h
|
||||
* @return a native pointer to a PathConsumerVec structure.
|
||||
*/
|
||||
public long getNativeConsumer();
|
||||
}
|
||||
319
jdkSrc/jdk8/sun/awt/im/CompositionArea.java
Normal file
319
jdkSrc/jdk8/sun/awt/im/CompositionArea.java
Normal file
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.im;
|
||||
|
||||
import java.awt.AWTEvent;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.InputMethodEvent;
|
||||
import java.awt.event.InputMethodListener;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.TextHitInfo;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.im.InputMethodRequests;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
/**
|
||||
* A composition area is used to display text that's being composed
|
||||
* using an input method in its own user interface environment,
|
||||
* typically in a root window.
|
||||
*
|
||||
* @author JavaSoft International
|
||||
*/
|
||||
|
||||
// This class is final due to the 6607310 fix. Refer to the CR for details.
|
||||
public final class CompositionArea extends JPanel implements InputMethodListener {
|
||||
|
||||
private CompositionAreaHandler handler;
|
||||
|
||||
private TextLayout composedTextLayout;
|
||||
private TextHitInfo caret = null;
|
||||
private JFrame compositionWindow;
|
||||
private final static int TEXT_ORIGIN_X = 5;
|
||||
private final static int TEXT_ORIGIN_Y = 15;
|
||||
private final static int PASSIVE_WIDTH = 480;
|
||||
private final static int WIDTH_MARGIN=10;
|
||||
private final static int HEIGHT_MARGIN=3;
|
||||
|
||||
CompositionArea() {
|
||||
// create composition window with localized title
|
||||
String windowTitle = Toolkit.getProperty("AWT.CompositionWindowTitle", "Input Window");
|
||||
compositionWindow =
|
||||
(JFrame)InputMethodContext.createInputMethodWindow(windowTitle, null, true);
|
||||
|
||||
setOpaque(true);
|
||||
setBorder(LineBorder.createGrayLineBorder());
|
||||
setForeground(Color.black);
|
||||
setBackground(Color.white);
|
||||
|
||||
// if we get the focus, we still want to let the client's
|
||||
// input context handle the event
|
||||
enableInputMethods(true);
|
||||
enableEvents(AWTEvent.KEY_EVENT_MASK);
|
||||
|
||||
compositionWindow.getContentPane().add(this);
|
||||
compositionWindow.addWindowListener(new FrameWindowAdapter());
|
||||
addInputMethodListener(this);
|
||||
compositionWindow.enableInputMethods(false);
|
||||
compositionWindow.pack();
|
||||
Dimension windowSize = compositionWindow.getSize();
|
||||
Dimension screenSize = (getToolkit()).getScreenSize();
|
||||
compositionWindow.setLocation(screenSize.width - windowSize.width-20,
|
||||
screenSize.height - windowSize.height-100);
|
||||
compositionWindow.setVisible(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the composition area handler that currently owns this
|
||||
* composition area, and its input context.
|
||||
*/
|
||||
synchronized void setHandlerInfo(CompositionAreaHandler handler, InputContext inputContext) {
|
||||
this.handler = handler;
|
||||
((InputMethodWindow) compositionWindow).setInputContext(inputContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.Component#getInputMethodRequests
|
||||
*/
|
||||
public InputMethodRequests getInputMethodRequests() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
// returns a 0-width rectangle
|
||||
private Rectangle getCaretRectangle(TextHitInfo caret) {
|
||||
int caretLocation = 0;
|
||||
TextLayout layout = composedTextLayout;
|
||||
if (layout != null) {
|
||||
caretLocation = Math.round(layout.getCaretInfo(caret)[0]);
|
||||
}
|
||||
Graphics g = getGraphics();
|
||||
FontMetrics metrics = null;
|
||||
try {
|
||||
metrics = g.getFontMetrics();
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
return new Rectangle(TEXT_ORIGIN_X + caretLocation,
|
||||
TEXT_ORIGIN_Y - metrics.getAscent(),
|
||||
0, metrics.getAscent() + metrics.getDescent());
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
g.setColor(getForeground());
|
||||
TextLayout layout = composedTextLayout;
|
||||
if (layout != null) {
|
||||
layout.draw((Graphics2D) g, TEXT_ORIGIN_X, TEXT_ORIGIN_Y);
|
||||
}
|
||||
if (caret != null) {
|
||||
Rectangle rectangle = getCaretRectangle(caret);
|
||||
g.setXORMode(getBackground());
|
||||
g.fillRect(rectangle.x, rectangle.y, 1, rectangle.height);
|
||||
g.setPaintMode();
|
||||
}
|
||||
}
|
||||
|
||||
// shows/hides the composition window
|
||||
void setCompositionAreaVisible(boolean visible) {
|
||||
compositionWindow.setVisible(visible);
|
||||
}
|
||||
|
||||
// returns true if composition area is visible
|
||||
boolean isCompositionAreaVisible() {
|
||||
return compositionWindow.isVisible();
|
||||
}
|
||||
|
||||
// workaround for the Solaris focus lost problem
|
||||
class FrameWindowAdapter extends WindowAdapter {
|
||||
public void windowActivated(WindowEvent e) {
|
||||
requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
// InputMethodListener methods - just forward to the current handler
|
||||
public void inputMethodTextChanged(InputMethodEvent event) {
|
||||
handler.inputMethodTextChanged(event);
|
||||
}
|
||||
|
||||
public void caretPositionChanged(InputMethodEvent event) {
|
||||
handler.caretPositionChanged(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text and caret to be displayed in this composition area.
|
||||
* Shows the window if it contains text, hides it if not.
|
||||
*/
|
||||
void setText(AttributedCharacterIterator composedText, TextHitInfo caret) {
|
||||
composedTextLayout = null;
|
||||
if (composedText == null) {
|
||||
// there's no composed text to display, so hide the window
|
||||
compositionWindow.setVisible(false);
|
||||
this.caret = null;
|
||||
} else {
|
||||
/* since we have composed text, make sure the window is shown.
|
||||
This is necessary to get a valid graphics object. See 6181385.
|
||||
*/
|
||||
if (!compositionWindow.isVisible()) {
|
||||
compositionWindow.setVisible(true);
|
||||
}
|
||||
|
||||
Graphics g = getGraphics();
|
||||
|
||||
if (g == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
updateWindowLocation();
|
||||
|
||||
FontRenderContext context = ((Graphics2D)g).getFontRenderContext();
|
||||
composedTextLayout = new TextLayout(composedText, context);
|
||||
Rectangle2D bounds = composedTextLayout.getBounds();
|
||||
|
||||
this.caret = caret;
|
||||
|
||||
// Resize the composition area to just fit the text.
|
||||
FontMetrics metrics = g.getFontMetrics();
|
||||
Rectangle2D maxCharBoundsRec = metrics.getMaxCharBounds(g);
|
||||
int newHeight = (int)maxCharBoundsRec.getHeight() + HEIGHT_MARGIN;
|
||||
int newFrameHeight = newHeight +compositionWindow.getInsets().top
|
||||
+compositionWindow.getInsets().bottom;
|
||||
// If it's a passive client, set the width always to PASSIVE_WIDTH (480px)
|
||||
InputMethodRequests req = handler.getClientInputMethodRequests();
|
||||
int newWidth = (req==null) ? PASSIVE_WIDTH : (int)bounds.getWidth() + WIDTH_MARGIN;
|
||||
int newFrameWidth = newWidth + compositionWindow.getInsets().left
|
||||
+ compositionWindow.getInsets().right;
|
||||
setPreferredSize(new Dimension(newWidth, newHeight));
|
||||
compositionWindow.setSize(new Dimension(newFrameWidth, newFrameHeight));
|
||||
|
||||
// show the composed text
|
||||
paint(g);
|
||||
}
|
||||
finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the caret to be displayed in this composition area.
|
||||
* The text is not changed.
|
||||
*/
|
||||
void setCaret(TextHitInfo caret) {
|
||||
this.caret = caret;
|
||||
if (compositionWindow.isVisible()) {
|
||||
Graphics g = getGraphics();
|
||||
try {
|
||||
paint(g);
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Positions the composition window near (usually below) the
|
||||
* insertion point in the client component if the client
|
||||
* component is an active client (below-the-spot input).
|
||||
*/
|
||||
void updateWindowLocation() {
|
||||
InputMethodRequests req = handler.getClientInputMethodRequests();
|
||||
if (req == null) {
|
||||
// not an active client
|
||||
return;
|
||||
}
|
||||
|
||||
Point windowLocation = new Point();
|
||||
|
||||
Rectangle caretRect = req.getTextLocation(null);
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
Dimension windowSize = compositionWindow.getSize();
|
||||
final int SPACING = 2;
|
||||
|
||||
if (caretRect.x + windowSize.width > screenSize.width) {
|
||||
windowLocation.x = screenSize.width - windowSize.width;
|
||||
} else {
|
||||
windowLocation.x = caretRect.x;
|
||||
}
|
||||
|
||||
if (caretRect.y + caretRect.height + SPACING + windowSize.height > screenSize.height) {
|
||||
windowLocation.y = caretRect.y - SPACING - windowSize.height;
|
||||
} else {
|
||||
windowLocation.y = caretRect.y + caretRect.height + SPACING;
|
||||
}
|
||||
|
||||
compositionWindow.setLocation(windowLocation);
|
||||
}
|
||||
|
||||
// support for InputMethodRequests methods
|
||||
Rectangle getTextLocation(TextHitInfo offset) {
|
||||
Rectangle rectangle = getCaretRectangle(offset);
|
||||
Point location = getLocationOnScreen();
|
||||
rectangle.translate(location.x, location.y);
|
||||
return rectangle;
|
||||
}
|
||||
|
||||
TextHitInfo getLocationOffset(int x, int y) {
|
||||
TextLayout layout = composedTextLayout;
|
||||
if (layout == null) {
|
||||
return null;
|
||||
} else {
|
||||
Point location = getLocationOnScreen();
|
||||
x -= location.x + TEXT_ORIGIN_X;
|
||||
y -= location.y + TEXT_ORIGIN_Y;
|
||||
if (layout.getBounds().contains(x, y)) {
|
||||
return layout.hitTestChar(x, y);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disables or enables decorations of the composition window
|
||||
void setCompositionAreaUndecorated(boolean setUndecorated){
|
||||
if (compositionWindow.isDisplayable()){
|
||||
compositionWindow.removeNotify();
|
||||
}
|
||||
compositionWindow.setUndecorated(setUndecorated);
|
||||
compositionWindow.pack();
|
||||
}
|
||||
|
||||
// Proclaim serial compatibility with 1.7.0
|
||||
private static final long serialVersionUID = -1057247068746557444L;
|
||||
|
||||
}
|
||||
354
jdkSrc/jdk8/sun/awt/im/CompositionAreaHandler.java
Normal file
354
jdkSrc/jdk8/sun/awt/im/CompositionAreaHandler.java
Normal file
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, 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.im;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.InputMethodEvent;
|
||||
import java.awt.event.InputMethodListener;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.font.TextHitInfo;
|
||||
import java.awt.im.InputMethodRequests;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.AttributedCharacterIterator.Attribute;
|
||||
import java.text.AttributedString;
|
||||
|
||||
/**
|
||||
* A composition area handler handles events and input method requests for
|
||||
* the composition area. Typically each input method context has its own
|
||||
* composition area handler if it supports passive clients or below-the-spot
|
||||
* input, but all handlers share a single composition area.
|
||||
*
|
||||
* @author JavaSoft International
|
||||
*/
|
||||
|
||||
class CompositionAreaHandler implements InputMethodListener,
|
||||
InputMethodRequests {
|
||||
|
||||
private static CompositionArea compositionArea;
|
||||
private static Object compositionAreaLock = new Object();
|
||||
private static CompositionAreaHandler compositionAreaOwner; // synchronized through compositionArea
|
||||
|
||||
private AttributedCharacterIterator composedText;
|
||||
private TextHitInfo caret = null;
|
||||
private WeakReference<Component> clientComponent = new WeakReference<>(null);
|
||||
private InputMethodContext inputMethodContext;
|
||||
|
||||
/**
|
||||
* Constructs the composition area handler.
|
||||
*/
|
||||
CompositionAreaHandler(InputMethodContext context) {
|
||||
inputMethodContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the composition area.
|
||||
*/
|
||||
private void createCompositionArea() {
|
||||
synchronized(compositionAreaLock) {
|
||||
compositionArea = new CompositionArea();
|
||||
if (compositionAreaOwner != null) {
|
||||
compositionArea.setHandlerInfo(compositionAreaOwner, inputMethodContext);
|
||||
}
|
||||
// If the client component is an active client using below-the-spot style, then
|
||||
// make the composition window undecorated without a title bar.
|
||||
Component client = clientComponent.get();
|
||||
if(client != null){
|
||||
InputMethodRequests req = client.getInputMethodRequests();
|
||||
if (req != null && inputMethodContext.useBelowTheSpotInput()) {
|
||||
setCompositionAreaUndecorated(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setClientComponent(Component clientComponent) {
|
||||
this.clientComponent = new WeakReference<>(clientComponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the composition area, makes this handler its owner, and installs
|
||||
* the handler and its input context into the composition area for event
|
||||
* and input method request handling.
|
||||
* If doUpdate is true, updates the composition area with previously sent
|
||||
* composed text.
|
||||
*/
|
||||
|
||||
void grabCompositionArea(boolean doUpdate) {
|
||||
synchronized (compositionAreaLock) {
|
||||
if (compositionAreaOwner != this) {
|
||||
compositionAreaOwner = this;
|
||||
if (compositionArea != null) {
|
||||
compositionArea.setHandlerInfo(this, inputMethodContext);
|
||||
}
|
||||
if (doUpdate) {
|
||||
// Create the composition area if necessary
|
||||
if ((composedText != null) && (compositionArea == null)) {
|
||||
createCompositionArea();
|
||||
}
|
||||
if (compositionArea != null) {
|
||||
compositionArea.setText(composedText, caret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases and closes the composition area if it is currently owned by
|
||||
* this composition area handler.
|
||||
*/
|
||||
void releaseCompositionArea() {
|
||||
synchronized (compositionAreaLock) {
|
||||
if (compositionAreaOwner == this) {
|
||||
compositionAreaOwner = null;
|
||||
if (compositionArea != null) {
|
||||
compositionArea.setHandlerInfo(null, null);
|
||||
compositionArea.setText(null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases and closes the composition area if it has been created,
|
||||
* independent of the current owner.
|
||||
*/
|
||||
static void closeCompositionArea() {
|
||||
if (compositionArea != null) {
|
||||
synchronized (compositionAreaLock) {
|
||||
compositionAreaOwner = null;
|
||||
compositionArea.setHandlerInfo(null, null);
|
||||
compositionArea.setText(null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the composition area is currently visible
|
||||
*/
|
||||
boolean isCompositionAreaVisible() {
|
||||
if (compositionArea != null) {
|
||||
return compositionArea.isCompositionAreaVisible();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shows or hides the composition Area
|
||||
*/
|
||||
void setCompositionAreaVisible(boolean visible) {
|
||||
if (compositionArea != null) {
|
||||
compositionArea.setCompositionAreaVisible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
void processInputMethodEvent(InputMethodEvent event) {
|
||||
if (event.getID() == InputMethodEvent.INPUT_METHOD_TEXT_CHANGED) {
|
||||
inputMethodTextChanged(event);
|
||||
} else {
|
||||
caretPositionChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set the compositionArea frame decoration
|
||||
*/
|
||||
void setCompositionAreaUndecorated(boolean undecorated) {
|
||||
if (compositionArea != null) {
|
||||
compositionArea.setCompositionAreaUndecorated(undecorated);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// InputMethodListener methods
|
||||
//
|
||||
|
||||
private static final Attribute[] IM_ATTRIBUTES =
|
||||
{ TextAttribute.INPUT_METHOD_HIGHLIGHT };
|
||||
|
||||
public void inputMethodTextChanged(InputMethodEvent event) {
|
||||
AttributedCharacterIterator text = event.getText();
|
||||
int committedCharacterCount = event.getCommittedCharacterCount();
|
||||
|
||||
// extract composed text and prepare it for display
|
||||
composedText = null;
|
||||
caret = null;
|
||||
if (text != null
|
||||
&& committedCharacterCount < text.getEndIndex() - text.getBeginIndex()) {
|
||||
|
||||
// Create the composition area if necessary
|
||||
if (compositionArea == null) {
|
||||
createCompositionArea();
|
||||
}
|
||||
|
||||
// copy the composed text
|
||||
AttributedString composedTextString;
|
||||
composedTextString = new AttributedString(text,
|
||||
text.getBeginIndex() + committedCharacterCount, // skip over committed text
|
||||
text.getEndIndex(), IM_ATTRIBUTES);
|
||||
composedTextString.addAttribute(TextAttribute.FONT, compositionArea.getFont());
|
||||
composedText = composedTextString.getIterator();
|
||||
caret = event.getCaret();
|
||||
}
|
||||
|
||||
if (compositionArea != null) {
|
||||
compositionArea.setText(composedText, caret);
|
||||
}
|
||||
|
||||
// send any committed text to the text component
|
||||
if (committedCharacterCount > 0) {
|
||||
inputMethodContext.dispatchCommittedText(((Component) event.getSource()),
|
||||
text, committedCharacterCount);
|
||||
|
||||
// this may have changed the text location, so reposition the window
|
||||
if (isCompositionAreaVisible()) {
|
||||
compositionArea.updateWindowLocation();
|
||||
}
|
||||
}
|
||||
|
||||
// event has been handled, so consume it
|
||||
event.consume();
|
||||
}
|
||||
|
||||
public void caretPositionChanged(InputMethodEvent event) {
|
||||
if (compositionArea != null) {
|
||||
compositionArea.setCaret(event.getCaret());
|
||||
}
|
||||
|
||||
// event has been handled, so consume it
|
||||
event.consume();
|
||||
}
|
||||
|
||||
//
|
||||
// InputMethodRequests methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Returns the input method request handler of the client component.
|
||||
* When using the composition window for an active client (below-the-spot
|
||||
* input), input method requests that do not relate to the display of
|
||||
* the composed text are forwarded to the client component.
|
||||
*/
|
||||
InputMethodRequests getClientInputMethodRequests() {
|
||||
Component client = clientComponent.get();
|
||||
if (client != null) {
|
||||
return client.getInputMethodRequests();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Rectangle getTextLocation(TextHitInfo offset) {
|
||||
synchronized (compositionAreaLock) {
|
||||
if (compositionAreaOwner == this && isCompositionAreaVisible()) {
|
||||
return compositionArea.getTextLocation(offset);
|
||||
} else if (composedText != null) {
|
||||
// there's composed text, but it's not displayed, so fake a rectangle
|
||||
return new Rectangle(0, 0, 0, 10);
|
||||
} else {
|
||||
InputMethodRequests requests = getClientInputMethodRequests();
|
||||
if (requests != null) {
|
||||
return requests.getTextLocation(offset);
|
||||
} else {
|
||||
// passive client, no composed text, so fake a rectangle
|
||||
return new Rectangle(0, 0, 0, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TextHitInfo getLocationOffset(int x, int y) {
|
||||
synchronized (compositionAreaLock) {
|
||||
if (compositionAreaOwner == this && isCompositionAreaVisible()) {
|
||||
return compositionArea.getLocationOffset(x, y);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getInsertPositionOffset() {
|
||||
InputMethodRequests req = getClientInputMethodRequests();
|
||||
if (req != null) {
|
||||
return req.getInsertPositionOffset();
|
||||
}
|
||||
|
||||
// we don't have access to the client component's text.
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static final AttributedCharacterIterator EMPTY_TEXT =
|
||||
(new AttributedString("")).getIterator();
|
||||
|
||||
public AttributedCharacterIterator getCommittedText(int beginIndex,
|
||||
int endIndex,
|
||||
Attribute[] attributes) {
|
||||
InputMethodRequests req = getClientInputMethodRequests();
|
||||
if(req != null) {
|
||||
return req.getCommittedText(beginIndex, endIndex, attributes);
|
||||
}
|
||||
|
||||
// we don't have access to the client component's text.
|
||||
return EMPTY_TEXT;
|
||||
}
|
||||
|
||||
public int getCommittedTextLength() {
|
||||
InputMethodRequests req = getClientInputMethodRequests();
|
||||
if(req != null) {
|
||||
return req.getCommittedTextLength();
|
||||
}
|
||||
|
||||
// we don't have access to the client component's text.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public AttributedCharacterIterator cancelLatestCommittedText(Attribute[] attributes) {
|
||||
InputMethodRequests req = getClientInputMethodRequests();
|
||||
if(req != null) {
|
||||
return req.cancelLatestCommittedText(attributes);
|
||||
}
|
||||
|
||||
// we don't have access to the client component's text.
|
||||
return null;
|
||||
}
|
||||
|
||||
public AttributedCharacterIterator getSelectedText(Attribute[] attributes) {
|
||||
InputMethodRequests req = getClientInputMethodRequests();
|
||||
if(req != null) {
|
||||
return req.getSelectedText(attributes);
|
||||
}
|
||||
|
||||
// we don't have access to the client component's text.
|
||||
return EMPTY_TEXT;
|
||||
}
|
||||
|
||||
}
|
||||
632
jdkSrc/jdk8/sun/awt/im/ExecutableInputMethodManager.java
Normal file
632
jdkSrc/jdk8/sun/awt/im/ExecutableInputMethodManager.java
Normal file
@@ -0,0 +1,632 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, 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.im;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.CheckboxMenuItem;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Frame;
|
||||
import java.awt.PopupMenu;
|
||||
import java.awt.Menu;
|
||||
import java.awt.MenuItem;
|
||||
import java.awt.Toolkit;
|
||||
import sun.awt.AppContext;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.InvocationEvent;
|
||||
import java.awt.im.spi.InputMethodDescriptor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Vector;
|
||||
import java.util.Set;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
import sun.awt.InputMethodSupport;
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
/**
|
||||
* <code>ExecutableInputMethodManager</code> is the implementation of the
|
||||
* <code>InputMethodManager</code> class. It is runnable as a separate
|
||||
* thread in the AWT environment.
|
||||
* <code>InputMethodManager.getInstance()</code> creates an instance of
|
||||
* <code>ExecutableInputMethodManager</code> and executes it as a deamon
|
||||
* thread.
|
||||
*
|
||||
* @see InputMethodManager
|
||||
*/
|
||||
class ExecutableInputMethodManager extends InputMethodManager
|
||||
implements Runnable
|
||||
{
|
||||
// the input context that's informed about selections from the user interface
|
||||
private InputContext currentInputContext;
|
||||
|
||||
// Menu item string for the trigger menu.
|
||||
private String triggerMenuString;
|
||||
|
||||
// popup menu for selecting an input method
|
||||
private InputMethodPopupMenu selectionMenu;
|
||||
private static String selectInputMethodMenuTitle;
|
||||
|
||||
// locator and name of host adapter
|
||||
private InputMethodLocator hostAdapterLocator;
|
||||
|
||||
// locators for Java input methods
|
||||
private int javaInputMethodCount; // number of Java input methods found
|
||||
private Vector<InputMethodLocator> javaInputMethodLocatorList;
|
||||
|
||||
// component that is requesting input method switch
|
||||
// must be Frame or Dialog
|
||||
private Component requestComponent;
|
||||
|
||||
// input context that is requesting input method switch
|
||||
private InputContext requestInputContext;
|
||||
|
||||
// IM preference stuff
|
||||
private static final String preferredIMNode = "/sun/awt/im/preferredInputMethod";
|
||||
private static final String descriptorKey = "descriptor";
|
||||
private Hashtable<String, InputMethodLocator> preferredLocatorCache = new Hashtable<>();
|
||||
private Preferences userRoot;
|
||||
|
||||
ExecutableInputMethodManager() {
|
||||
|
||||
// set up host adapter locator
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
try {
|
||||
if (toolkit instanceof InputMethodSupport) {
|
||||
InputMethodDescriptor hostAdapterDescriptor =
|
||||
((InputMethodSupport)toolkit)
|
||||
.getInputMethodAdapterDescriptor();
|
||||
if (hostAdapterDescriptor != null) {
|
||||
hostAdapterLocator = new InputMethodLocator(hostAdapterDescriptor, null, null);
|
||||
}
|
||||
}
|
||||
} catch (AWTException e) {
|
||||
// if we can't get a descriptor, we'll just have to do without native input methods
|
||||
}
|
||||
|
||||
javaInputMethodLocatorList = new Vector<InputMethodLocator>();
|
||||
initializeInputMethodLocatorList();
|
||||
}
|
||||
|
||||
synchronized void initialize() {
|
||||
selectInputMethodMenuTitle = Toolkit.getProperty("AWT.InputMethodSelectionMenu", "Select Input Method");
|
||||
|
||||
triggerMenuString = selectInputMethodMenuTitle;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
// If there are no multiple input methods to choose from, wait forever
|
||||
while (!hasMultipleInputMethods()) {
|
||||
try {
|
||||
synchronized (this) {
|
||||
wait();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Loop for processing input method change requests
|
||||
while (true) {
|
||||
waitForChangeRequest();
|
||||
initializeInputMethodLocatorList();
|
||||
try {
|
||||
if (requestComponent != null) {
|
||||
showInputMethodMenuOnRequesterEDT(requestComponent);
|
||||
} else {
|
||||
// show the popup menu within the event thread
|
||||
EventQueue.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
showInputMethodMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
} catch (InvocationTargetException ite) {
|
||||
// should we do anything under these exceptions?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shows Input Method Menu on the EDT of requester component
|
||||
// to avoid side effects. See 6544309.
|
||||
private void showInputMethodMenuOnRequesterEDT(Component requester)
|
||||
throws InterruptedException, InvocationTargetException {
|
||||
|
||||
if (requester == null){
|
||||
return;
|
||||
}
|
||||
|
||||
class AWTInvocationLock {}
|
||||
Object lock = new AWTInvocationLock();
|
||||
|
||||
InvocationEvent event =
|
||||
new InvocationEvent(requester,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
showInputMethodMenu();
|
||||
}
|
||||
},
|
||||
lock,
|
||||
true);
|
||||
|
||||
AppContext requesterAppContext = SunToolkit.targetToAppContext(requester);
|
||||
synchronized (lock) {
|
||||
SunToolkit.postEvent(requesterAppContext, event);
|
||||
while (!event.isDispatched()) {
|
||||
lock.wait();
|
||||
}
|
||||
}
|
||||
|
||||
Throwable eventThrowable = event.getThrowable();
|
||||
if (eventThrowable != null) {
|
||||
throw new InvocationTargetException(eventThrowable);
|
||||
}
|
||||
}
|
||||
|
||||
void setInputContext(InputContext inputContext) {
|
||||
if (currentInputContext != null && inputContext != null) {
|
||||
// don't throw this exception until 4237852 is fixed
|
||||
// throw new IllegalStateException("Can't have two active InputContext at the same time");
|
||||
}
|
||||
currentInputContext = inputContext;
|
||||
}
|
||||
|
||||
public synchronized void notifyChangeRequest(Component comp) {
|
||||
if (!(comp instanceof Frame || comp instanceof Dialog))
|
||||
return;
|
||||
|
||||
// if busy with the current request, ignore this request.
|
||||
if (requestComponent != null)
|
||||
return;
|
||||
|
||||
requestComponent = comp;
|
||||
notify();
|
||||
}
|
||||
|
||||
public synchronized void notifyChangeRequestByHotKey(Component comp) {
|
||||
while (!(comp instanceof Frame || comp instanceof Dialog)) {
|
||||
if (comp == null) {
|
||||
// no Frame or Dialog found in containment hierarchy.
|
||||
return;
|
||||
}
|
||||
comp = comp.getParent();
|
||||
}
|
||||
|
||||
notifyChangeRequest(comp);
|
||||
}
|
||||
|
||||
public String getTriggerMenuString() {
|
||||
return triggerMenuString;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the environment indicates there are multiple input methods
|
||||
*/
|
||||
boolean hasMultipleInputMethods() {
|
||||
return ((hostAdapterLocator != null) && (javaInputMethodCount > 0)
|
||||
|| (javaInputMethodCount > 1));
|
||||
}
|
||||
|
||||
private synchronized void waitForChangeRequest() {
|
||||
try {
|
||||
while (requestComponent == null) {
|
||||
wait();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* initializes the input method locator list for all
|
||||
* installed input method descriptors.
|
||||
*/
|
||||
private void initializeInputMethodLocatorList() {
|
||||
synchronized (javaInputMethodLocatorList) {
|
||||
javaInputMethodLocatorList.clear();
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
public Object run() {
|
||||
for (InputMethodDescriptor descriptor :
|
||||
ServiceLoader.loadInstalled(InputMethodDescriptor.class)) {
|
||||
ClassLoader cl = descriptor.getClass().getClassLoader();
|
||||
javaInputMethodLocatorList.add(new InputMethodLocator(descriptor, cl, null));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
javaInputMethodCount = javaInputMethodLocatorList.size();
|
||||
}
|
||||
|
||||
if (hasMultipleInputMethods()) {
|
||||
// initialize preferences
|
||||
if (userRoot == null) {
|
||||
userRoot = getUserRoot();
|
||||
}
|
||||
} else {
|
||||
// indicate to clients not to offer the menu
|
||||
triggerMenuString = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void showInputMethodMenu() {
|
||||
|
||||
if (!hasMultipleInputMethods()) {
|
||||
requestComponent = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize pop-up menu
|
||||
selectionMenu = InputMethodPopupMenu.getInstance(requestComponent, selectInputMethodMenuTitle);
|
||||
|
||||
// we have to rebuild the menu each time because
|
||||
// some input methods (such as IIIMP) may change
|
||||
// their list of supported locales dynamically
|
||||
selectionMenu.removeAll();
|
||||
|
||||
// get information about the currently selected input method
|
||||
// ??? if there's no current input context, what's the point
|
||||
// of showing the menu?
|
||||
String currentSelection = getCurrentSelection();
|
||||
|
||||
// Add menu item for host adapter
|
||||
if (hostAdapterLocator != null) {
|
||||
selectionMenu.addOneInputMethodToMenu(hostAdapterLocator, currentSelection);
|
||||
selectionMenu.addSeparator();
|
||||
}
|
||||
|
||||
// Add menu items for other input methods
|
||||
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
|
||||
InputMethodLocator locator = javaInputMethodLocatorList.get(i);
|
||||
selectionMenu.addOneInputMethodToMenu(locator, currentSelection);
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
selectionMenu.addToComponent(requestComponent);
|
||||
requestInputContext = currentInputContext;
|
||||
selectionMenu.show(requestComponent, 60, 80); // TODO: get proper x, y...
|
||||
requestComponent = null;
|
||||
}
|
||||
}
|
||||
|
||||
private String getCurrentSelection() {
|
||||
InputContext inputContext = currentInputContext;
|
||||
if (inputContext != null) {
|
||||
InputMethodLocator locator = inputContext.getInputMethodLocator();
|
||||
if (locator != null) {
|
||||
return locator.getActionCommandString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
synchronized void changeInputMethod(String choice) {
|
||||
InputMethodLocator locator = null;
|
||||
|
||||
String inputMethodName = choice;
|
||||
String localeString = null;
|
||||
int index = choice.indexOf('\n');
|
||||
if (index != -1) {
|
||||
localeString = choice.substring(index + 1);
|
||||
inputMethodName = choice.substring(0, index);
|
||||
}
|
||||
if (hostAdapterLocator.getActionCommandString().equals(inputMethodName)) {
|
||||
locator = hostAdapterLocator;
|
||||
} else {
|
||||
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
|
||||
InputMethodLocator candidate = javaInputMethodLocatorList.get(i);
|
||||
String name = candidate.getActionCommandString();
|
||||
if (name.equals(inputMethodName)) {
|
||||
locator = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (locator != null && localeString != null) {
|
||||
String language = "", country = "", variant = "";
|
||||
int postIndex = localeString.indexOf('_');
|
||||
if (postIndex == -1) {
|
||||
language = localeString;
|
||||
} else {
|
||||
language = localeString.substring(0, postIndex);
|
||||
int preIndex = postIndex + 1;
|
||||
postIndex = localeString.indexOf('_', preIndex);
|
||||
if (postIndex == -1) {
|
||||
country = localeString.substring(preIndex);
|
||||
} else {
|
||||
country = localeString.substring(preIndex, postIndex);
|
||||
variant = localeString.substring(postIndex + 1);
|
||||
}
|
||||
}
|
||||
Locale locale = new Locale(language, country, variant);
|
||||
locator = locator.deriveLocator(locale);
|
||||
}
|
||||
|
||||
if (locator == null)
|
||||
return;
|
||||
|
||||
// tell the input context about the change
|
||||
if (requestInputContext != null) {
|
||||
requestInputContext.changeInputMethod(locator);
|
||||
requestInputContext = null;
|
||||
|
||||
// remember the selection
|
||||
putPreferredInputMethod(locator);
|
||||
}
|
||||
}
|
||||
|
||||
InputMethodLocator findInputMethod(Locale locale) {
|
||||
// look for preferred input method first
|
||||
InputMethodLocator locator = getPreferredInputMethod(locale);
|
||||
if (locator != null) {
|
||||
return locator;
|
||||
}
|
||||
|
||||
if (hostAdapterLocator != null && hostAdapterLocator.isLocaleAvailable(locale)) {
|
||||
return hostAdapterLocator.deriveLocator(locale);
|
||||
}
|
||||
|
||||
// Update the locator list
|
||||
initializeInputMethodLocatorList();
|
||||
|
||||
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
|
||||
InputMethodLocator candidate = javaInputMethodLocatorList.get(i);
|
||||
if (candidate.isLocaleAvailable(locale)) {
|
||||
return candidate.deriveLocator(locale);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Locale getDefaultKeyboardLocale() {
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
if (toolkit instanceof InputMethodSupport) {
|
||||
return ((InputMethodSupport)toolkit).getDefaultKeyboardLocale();
|
||||
} else {
|
||||
return Locale.getDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a InputMethodLocator object that the
|
||||
* user prefers for the given locale.
|
||||
*
|
||||
* @param locale Locale for which the user prefers the input method.
|
||||
*/
|
||||
private synchronized InputMethodLocator getPreferredInputMethod(Locale locale) {
|
||||
InputMethodLocator preferredLocator = null;
|
||||
|
||||
if (!hasMultipleInputMethods()) {
|
||||
// No need to look for a preferred Java input method
|
||||
return null;
|
||||
}
|
||||
|
||||
// look for the cached preference first.
|
||||
preferredLocator = preferredLocatorCache.get(locale.toString().intern());
|
||||
if (preferredLocator != null) {
|
||||
return preferredLocator;
|
||||
}
|
||||
|
||||
// look for the preference in the user preference tree
|
||||
String nodePath = findPreferredInputMethodNode(locale);
|
||||
String descriptorName = readPreferredInputMethod(nodePath);
|
||||
Locale advertised;
|
||||
|
||||
// get the locator object
|
||||
if (descriptorName != null) {
|
||||
// check for the host adapter first
|
||||
if (hostAdapterLocator != null &&
|
||||
hostAdapterLocator.getDescriptor().getClass().getName().equals(descriptorName)) {
|
||||
advertised = getAdvertisedLocale(hostAdapterLocator, locale);
|
||||
if (advertised != null) {
|
||||
preferredLocator = hostAdapterLocator.deriveLocator(advertised);
|
||||
preferredLocatorCache.put(locale.toString().intern(), preferredLocator);
|
||||
}
|
||||
return preferredLocator;
|
||||
}
|
||||
// look for Java input methods
|
||||
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
|
||||
InputMethodLocator locator = javaInputMethodLocatorList.get(i);
|
||||
InputMethodDescriptor descriptor = locator.getDescriptor();
|
||||
if (descriptor.getClass().getName().equals(descriptorName)) {
|
||||
advertised = getAdvertisedLocale(locator, locale);
|
||||
if (advertised != null) {
|
||||
preferredLocator = locator.deriveLocator(advertised);
|
||||
preferredLocatorCache.put(locale.toString().intern(), preferredLocator);
|
||||
}
|
||||
return preferredLocator;
|
||||
}
|
||||
}
|
||||
|
||||
// maybe preferred input method information is bogus.
|
||||
writePreferredInputMethod(nodePath, null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String findPreferredInputMethodNode(Locale locale) {
|
||||
if (userRoot == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// create locale node relative path
|
||||
String nodePath = preferredIMNode + "/" + createLocalePath(locale);
|
||||
|
||||
// look for the descriptor
|
||||
while (!nodePath.equals(preferredIMNode)) {
|
||||
try {
|
||||
if (userRoot.nodeExists(nodePath)) {
|
||||
if (readPreferredInputMethod(nodePath) != null) {
|
||||
return nodePath;
|
||||
}
|
||||
}
|
||||
} catch (BackingStoreException bse) {
|
||||
}
|
||||
|
||||
// search at parent's node
|
||||
nodePath = nodePath.substring(0, nodePath.lastIndexOf('/'));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String readPreferredInputMethod(String nodePath) {
|
||||
if ((userRoot == null) || (nodePath == null)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return userRoot.node(nodePath).get(descriptorKey, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the preferred input method descriptor class name into
|
||||
* the user's Preferences tree in accordance with the given locale.
|
||||
*
|
||||
* @param inputMethodLocator input method locator to remember.
|
||||
*/
|
||||
private synchronized void putPreferredInputMethod(InputMethodLocator locator) {
|
||||
InputMethodDescriptor descriptor = locator.getDescriptor();
|
||||
Locale preferredLocale = locator.getLocale();
|
||||
|
||||
if (preferredLocale == null) {
|
||||
// check available locales of the input method
|
||||
try {
|
||||
Locale[] availableLocales = descriptor.getAvailableLocales();
|
||||
if (availableLocales.length == 1) {
|
||||
preferredLocale = availableLocales[0];
|
||||
} else {
|
||||
// there is no way to know which locale is the preferred one, so do nothing.
|
||||
return;
|
||||
}
|
||||
} catch (AWTException ae) {
|
||||
// do nothing here, either.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// for regions that have only one language, we need to regard
|
||||
// "xx_YY" as "xx" when putting the preference into tree
|
||||
if (preferredLocale.equals(Locale.JAPAN)) {
|
||||
preferredLocale = Locale.JAPANESE;
|
||||
}
|
||||
if (preferredLocale.equals(Locale.KOREA)) {
|
||||
preferredLocale = Locale.KOREAN;
|
||||
}
|
||||
if (preferredLocale.equals(new Locale("th", "TH"))) {
|
||||
preferredLocale = new Locale("th");
|
||||
}
|
||||
|
||||
// obtain node
|
||||
String path = preferredIMNode + "/" + createLocalePath(preferredLocale);
|
||||
|
||||
// write in the preference tree
|
||||
writePreferredInputMethod(path, descriptor.getClass().getName());
|
||||
preferredLocatorCache.put(preferredLocale.toString().intern(),
|
||||
locator.deriveLocator(preferredLocale));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private String createLocalePath(Locale locale) {
|
||||
String language = locale.getLanguage();
|
||||
String country = locale.getCountry();
|
||||
String variant = locale.getVariant();
|
||||
String localePath = null;
|
||||
if (!variant.equals("")) {
|
||||
localePath = "_" + language + "/_" + country + "/_" + variant;
|
||||
} else if (!country.equals("")) {
|
||||
localePath = "_" + language + "/_" + country;
|
||||
} else {
|
||||
localePath = "_" + language;
|
||||
}
|
||||
|
||||
return localePath;
|
||||
}
|
||||
|
||||
private void writePreferredInputMethod(String path, String descriptorName) {
|
||||
if (userRoot != null) {
|
||||
Preferences node = userRoot.node(path);
|
||||
|
||||
// record it
|
||||
if (descriptorName != null) {
|
||||
node.put(descriptorKey, descriptorName);
|
||||
} else {
|
||||
node.remove(descriptorKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Preferences getUserRoot() {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Preferences>() {
|
||||
public Preferences run() {
|
||||
return Preferences.userRoot();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Locale getAdvertisedLocale(InputMethodLocator locator, Locale locale) {
|
||||
Locale advertised = null;
|
||||
|
||||
if (locator.isLocaleAvailable(locale)) {
|
||||
advertised = locale;
|
||||
} else if (locale.getLanguage().equals("ja")) {
|
||||
// for Japanese, Korean, and Thai, check whether the input method supports
|
||||
// language or language_COUNTRY.
|
||||
if (locator.isLocaleAvailable(Locale.JAPAN)) {
|
||||
advertised = Locale.JAPAN;
|
||||
} else if (locator.isLocaleAvailable(Locale.JAPANESE)) {
|
||||
advertised = Locale.JAPANESE;
|
||||
}
|
||||
} else if (locale.getLanguage().equals("ko")) {
|
||||
if (locator.isLocaleAvailable(Locale.KOREA)) {
|
||||
advertised = Locale.KOREA;
|
||||
} else if (locator.isLocaleAvailable(Locale.KOREAN)) {
|
||||
advertised = Locale.KOREAN;
|
||||
}
|
||||
} else if (locale.getLanguage().equals("th")) {
|
||||
if (locator.isLocaleAvailable(new Locale("th", "TH"))) {
|
||||
advertised = new Locale("th", "TH");
|
||||
} else if (locator.isLocaleAvailable(new Locale("th"))) {
|
||||
advertised = new Locale("th");
|
||||
}
|
||||
}
|
||||
|
||||
return advertised;
|
||||
}
|
||||
}
|
||||
1068
jdkSrc/jdk8/sun/awt/im/InputContext.java
Normal file
1068
jdkSrc/jdk8/sun/awt/im/InputContext.java
Normal file
File diff suppressed because it is too large
Load Diff
117
jdkSrc/jdk8/sun/awt/im/InputMethodAdapter.java
Normal file
117
jdkSrc/jdk8/sun/awt/im/InputMethodAdapter.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, 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.im;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.im.spi.InputMethod;
|
||||
|
||||
/**
|
||||
* An input method adapter interfaces with the native input methods
|
||||
* on a host platform. In general, it looks to the input method
|
||||
* framework like a Java input method (that may support a few more
|
||||
* locales than a typical Java input method). However, since it
|
||||
* often has to work in a slightly hostile environment that's not
|
||||
* designed for easy integration into the Java input method
|
||||
* framework, it gets some special treatment that's not available
|
||||
* to Java input methods.
|
||||
* <p>
|
||||
* Licensees are free to modify this class as necessary to implement
|
||||
* their host input method adapters.
|
||||
*
|
||||
* @author JavaSoft International
|
||||
*/
|
||||
|
||||
public abstract class InputMethodAdapter implements InputMethod {
|
||||
|
||||
private Component clientComponent;
|
||||
|
||||
void setClientComponent(Component client) {
|
||||
clientComponent = client;
|
||||
}
|
||||
|
||||
protected Component getClientComponent() {
|
||||
return clientComponent;
|
||||
}
|
||||
|
||||
protected boolean haveActiveClient() {
|
||||
return clientComponent != null && clientComponent.getInputMethodRequests() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs the input method adapter about the component that has the AWT
|
||||
* focus if it's using the input context owning this adapter instance.
|
||||
*/
|
||||
protected void setAWTFocussedComponent(Component component) {
|
||||
// ignore - adapters can override if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether host input methods can support below-the-spot input.
|
||||
* Returns false by default.
|
||||
*/
|
||||
protected boolean supportsBelowTheSpot() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs the input method adapter not to listen to the native events.
|
||||
*/
|
||||
protected void stopListening() {
|
||||
// ignore - adapters can override if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies client Window location or status changes
|
||||
*/
|
||||
public void notifyClientWindowChange(Rectangle location) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts reconvertion. An implementing host adapter has to override
|
||||
* this method if it can support reconvert().
|
||||
* @exception UnsupportedOperationException when the adapter does not override
|
||||
* the method.
|
||||
*/
|
||||
public void reconvert() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the native input method. This method is provided for explicitly
|
||||
* turning off the native IM. The native IM is not turned off
|
||||
* when the native input method is deactivated. This method is
|
||||
* always called on AWT EDT. See details in bug 6226489.
|
||||
*/
|
||||
public abstract void disableInputMethod();
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string with information about the native input method, or
|
||||
* null.
|
||||
*/
|
||||
public abstract String getNativeInputMethodInfo();
|
||||
}
|
||||
377
jdkSrc/jdk8/sun/awt/im/InputMethodContext.java
Normal file
377
jdkSrc/jdk8/sun/awt/im/InputMethodContext.java
Normal file
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, 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.im;
|
||||
|
||||
import java.awt.AWTEvent;
|
||||
import java.awt.Component;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.HeadlessException;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.InputMethodEvent;
|
||||
import java.awt.font.TextHitInfo;
|
||||
import java.awt.im.InputMethodRequests;
|
||||
import java.awt.im.spi.InputMethod;
|
||||
import java.security.AccessController;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.AttributedCharacterIterator.Attribute;
|
||||
import java.text.AttributedString;
|
||||
import java.text.CharacterIterator;
|
||||
import javax.swing.JFrame;
|
||||
import sun.awt.InputMethodSupport;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* The InputMethodContext class provides methods that input methods
|
||||
* can use to communicate with their client components.
|
||||
* It is a subclass of InputContext, which provides methods for use by
|
||||
* components.
|
||||
*
|
||||
* @author JavaSoft International
|
||||
*/
|
||||
|
||||
public class InputMethodContext
|
||||
extends sun.awt.im.InputContext
|
||||
implements java.awt.im.spi.InputMethodContext {
|
||||
|
||||
private boolean dispatchingCommittedText;
|
||||
|
||||
// Creation of the context's composition area handler is
|
||||
// delayed until we really need a composition area.
|
||||
private CompositionAreaHandler compositionAreaHandler;
|
||||
private Object compositionAreaHandlerLock = new Object();
|
||||
|
||||
static private boolean belowTheSpotInputRequested;
|
||||
private boolean inputMethodSupportsBelowTheSpot;
|
||||
|
||||
static {
|
||||
// check whether we should use below-the-spot input
|
||||
// get property from command line
|
||||
String inputStyle = AccessController.doPrivileged
|
||||
(new GetPropertyAction("java.awt.im.style", null));
|
||||
// get property from awt.properties file
|
||||
if (inputStyle == null) {
|
||||
inputStyle = Toolkit.getProperty("java.awt.im.style", null);
|
||||
}
|
||||
belowTheSpotInputRequested = "below-the-spot".equals(inputStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an InputMethodContext.
|
||||
*/
|
||||
public InputMethodContext() {
|
||||
super();
|
||||
}
|
||||
|
||||
void setInputMethodSupportsBelowTheSpot(boolean supported) {
|
||||
inputMethodSupportsBelowTheSpot = supported;
|
||||
}
|
||||
|
||||
boolean useBelowTheSpotInput() {
|
||||
return belowTheSpotInputRequested && inputMethodSupportsBelowTheSpot;
|
||||
}
|
||||
|
||||
private boolean haveActiveClient() {
|
||||
Component client = getClientComponent();
|
||||
return client != null
|
||||
&& client.getInputMethodRequests() != null;
|
||||
}
|
||||
|
||||
// implements java.awt.im.spi.InputMethodContext.dispatchInputMethodEvent
|
||||
public void dispatchInputMethodEvent(int id,
|
||||
AttributedCharacterIterator text, int committedCharacterCount,
|
||||
TextHitInfo caret, TextHitInfo visiblePosition) {
|
||||
// We need to record the client component as the source so
|
||||
// that we have correct information if we later have to break up this
|
||||
// event into key events.
|
||||
Component source;
|
||||
|
||||
source = getClientComponent();
|
||||
if (source != null) {
|
||||
InputMethodEvent event = new InputMethodEvent(source,
|
||||
id, text, committedCharacterCount, caret, visiblePosition);
|
||||
|
||||
if (haveActiveClient() && !useBelowTheSpotInput()) {
|
||||
source.dispatchEvent(event);
|
||||
} else {
|
||||
getCompositionAreaHandler(true).processInputMethodEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches committed text to a client component.
|
||||
* Called by composition window.
|
||||
*
|
||||
* @param client The component that the text should get dispatched to.
|
||||
* @param text The iterator providing access to the committed
|
||||
* (and possible composed) text.
|
||||
* @param committedCharacterCount The number of committed characters in the text.
|
||||
*/
|
||||
synchronized void dispatchCommittedText(Component client,
|
||||
AttributedCharacterIterator text,
|
||||
int committedCharacterCount) {
|
||||
// note that the client is not always the current client component -
|
||||
// some host input method adapters may dispatch input method events
|
||||
// through the Java event queue, and we may have switched clients while
|
||||
// the event was in the queue.
|
||||
if (committedCharacterCount == 0
|
||||
|| text.getEndIndex() <= text.getBeginIndex()) {
|
||||
return;
|
||||
}
|
||||
long time = System.currentTimeMillis();
|
||||
dispatchingCommittedText = true;
|
||||
try {
|
||||
InputMethodRequests req = client.getInputMethodRequests();
|
||||
if (req != null) {
|
||||
// active client -> send text as InputMethodEvent
|
||||
int beginIndex = text.getBeginIndex();
|
||||
AttributedCharacterIterator toBeCommitted =
|
||||
(new AttributedString(text, beginIndex, beginIndex + committedCharacterCount)).getIterator();
|
||||
|
||||
InputMethodEvent inputEvent = new InputMethodEvent(
|
||||
client,
|
||||
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
|
||||
toBeCommitted,
|
||||
committedCharacterCount,
|
||||
null, null);
|
||||
|
||||
client.dispatchEvent(inputEvent);
|
||||
} else {
|
||||
// passive client -> send text as KeyEvents
|
||||
char keyChar = text.first();
|
||||
while (committedCharacterCount-- > 0 && keyChar != CharacterIterator.DONE) {
|
||||
KeyEvent keyEvent = new KeyEvent(client, KeyEvent.KEY_TYPED,
|
||||
time, 0, KeyEvent.VK_UNDEFINED, keyChar);
|
||||
client.dispatchEvent(keyEvent);
|
||||
keyChar = text.next();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
dispatchingCommittedText = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchEvent(AWTEvent event) {
|
||||
// some host input method adapters may dispatch input method events
|
||||
// through the Java event queue. If the component that the event is
|
||||
// intended for isn't an active client, or if we're using below-the-spot
|
||||
// input, we need to dispatch this event
|
||||
// to the input window. Note that that component is not necessarily the
|
||||
// current client component, since we may have switched clients while
|
||||
// the event was in the queue.
|
||||
if (event instanceof InputMethodEvent) {
|
||||
if (((Component) event.getSource()).getInputMethodRequests() == null
|
||||
|| (useBelowTheSpotInput() && !dispatchingCommittedText)) {
|
||||
getCompositionAreaHandler(true).processInputMethodEvent((InputMethodEvent) event);
|
||||
}
|
||||
} else {
|
||||
// make sure we don't dispatch our own key events back to the input method
|
||||
if (!dispatchingCommittedText) {
|
||||
super.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this context's composition area handler, creating it if necessary.
|
||||
* If requested, it grabs the composition area for use by this context.
|
||||
* The composition area's text is not updated.
|
||||
*/
|
||||
private CompositionAreaHandler getCompositionAreaHandler(boolean grab) {
|
||||
synchronized(compositionAreaHandlerLock) {
|
||||
if (compositionAreaHandler == null) {
|
||||
compositionAreaHandler = new CompositionAreaHandler(this);
|
||||
}
|
||||
compositionAreaHandler.setClientComponent(getClientComponent());
|
||||
if (grab) {
|
||||
compositionAreaHandler.grabCompositionArea(false);
|
||||
}
|
||||
|
||||
return compositionAreaHandler;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the composition area for use by this context.
|
||||
* If doUpdate is true, updates the composition area with previously sent
|
||||
* composed text.
|
||||
*/
|
||||
void grabCompositionArea(boolean doUpdate) {
|
||||
synchronized(compositionAreaHandlerLock) {
|
||||
if (compositionAreaHandler != null) {
|
||||
compositionAreaHandler.grabCompositionArea(doUpdate);
|
||||
} else {
|
||||
// if this context hasn't seen a need for a composition area yet,
|
||||
// just close it without creating the machinery
|
||||
CompositionAreaHandler.closeCompositionArea();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases and closes the composition area if it is currently owned by
|
||||
* this context's composition area handler.
|
||||
*/
|
||||
void releaseCompositionArea() {
|
||||
synchronized(compositionAreaHandlerLock) {
|
||||
if (compositionAreaHandler != null) {
|
||||
compositionAreaHandler.releaseCompositionArea();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls CompositionAreaHandler.isCompositionAreaVisible() to see
|
||||
* whether the composition area is visible or not.
|
||||
* Notice that this method is always called on the AWT event dispatch
|
||||
* thread.
|
||||
*/
|
||||
boolean isCompositionAreaVisible() {
|
||||
if (compositionAreaHandler != null) {
|
||||
return compositionAreaHandler.isCompositionAreaVisible();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Calls CompositionAreaHandler.setCompositionAreaVisible to
|
||||
* show or hide the composition area.
|
||||
* As isCompositionAreaVisible method, it is always called
|
||||
* on AWT event dispatch thread.
|
||||
*/
|
||||
void setCompositionAreaVisible(boolean visible) {
|
||||
if (compositionAreaHandler != null) {
|
||||
compositionAreaHandler.setCompositionAreaVisible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the current client component's implementation of getTextLocation.
|
||||
*/
|
||||
public Rectangle getTextLocation(TextHitInfo offset) {
|
||||
return getReq().getTextLocation(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the current client component's implementation of getLocationOffset.
|
||||
*/
|
||||
public TextHitInfo getLocationOffset(int x, int y) {
|
||||
return getReq().getLocationOffset(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the current client component's implementation of getInsertPositionOffset.
|
||||
*/
|
||||
public int getInsertPositionOffset() {
|
||||
return getReq().getInsertPositionOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the current client component's implementation of getCommittedText.
|
||||
*/
|
||||
public AttributedCharacterIterator getCommittedText(int beginIndex,
|
||||
int endIndex,
|
||||
Attribute[] attributes) {
|
||||
return getReq().getCommittedText(beginIndex, endIndex, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the current client component's implementation of getCommittedTextLength.
|
||||
*/
|
||||
public int getCommittedTextLength() {
|
||||
return getReq().getCommittedTextLength();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls the current client component's implementation of cancelLatestCommittedText.
|
||||
*/
|
||||
public AttributedCharacterIterator cancelLatestCommittedText(Attribute[] attributes) {
|
||||
return getReq().cancelLatestCommittedText(attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the current client component's implementation of getSelectedText.
|
||||
*/
|
||||
public AttributedCharacterIterator getSelectedText(Attribute[] attributes) {
|
||||
return getReq().getSelectedText(attributes);
|
||||
}
|
||||
|
||||
private InputMethodRequests getReq() {
|
||||
if (haveActiveClient() && !useBelowTheSpotInput()) {
|
||||
return getClientComponent().getInputMethodRequests();
|
||||
} else {
|
||||
return getCompositionAreaHandler(false);
|
||||
}
|
||||
}
|
||||
|
||||
// implements java.awt.im.spi.InputMethodContext.createInputMethodWindow
|
||||
public Window createInputMethodWindow(String title, boolean attachToInputContext) {
|
||||
InputContext context = attachToInputContext ? this : null;
|
||||
return createInputMethodWindow(title, context, false);
|
||||
}
|
||||
|
||||
// implements java.awt.im.spi.InputMethodContext.createInputMethodJFrame
|
||||
public JFrame createInputMethodJFrame(String title, boolean attachToInputContext) {
|
||||
InputContext context = attachToInputContext ? this : null;
|
||||
return (JFrame)createInputMethodWindow(title, context, true);
|
||||
}
|
||||
|
||||
static Window createInputMethodWindow(String title, InputContext context, boolean isSwing) {
|
||||
if (GraphicsEnvironment.isHeadless()) {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
if (isSwing) {
|
||||
return new InputMethodJFrame(title, context);
|
||||
} else {
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
if (toolkit instanceof InputMethodSupport) {
|
||||
return ((InputMethodSupport)toolkit).createInputMethodWindow(
|
||||
title, context);
|
||||
}
|
||||
}
|
||||
throw new InternalError("Input methods must be supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.im.spi.InputMethodContext#enableClientWindowNotification
|
||||
*/
|
||||
public void enableClientWindowNotification(InputMethod inputMethod, boolean enable) {
|
||||
super.enableClientWindowNotification(inputMethod, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables or enables decorations for the composition window.
|
||||
*/
|
||||
void setCompositionAreaUndecorated(boolean undecorated) {
|
||||
if (compositionAreaHandler != null) {
|
||||
compositionAreaHandler.setCompositionAreaUndecorated(undecorated);
|
||||
}
|
||||
}
|
||||
}
|
||||
74
jdkSrc/jdk8/sun/awt/im/InputMethodJFrame.java
Normal file
74
jdkSrc/jdk8/sun/awt/im/InputMethodJFrame.java
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2011, 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.im;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JRootPane;
|
||||
|
||||
/**
|
||||
* Implements a Swing based input method window that provides the minimal
|
||||
* functionality as specified in
|
||||
* {@link java.awt.im.spi.InputMethodContext#createInputMethodJFrame}.
|
||||
*
|
||||
*/
|
||||
public class InputMethodJFrame
|
||||
extends JFrame
|
||||
implements InputMethodWindow {
|
||||
|
||||
InputContext inputContext = null;
|
||||
|
||||
/**
|
||||
* Constructs a Swing based input method window.
|
||||
*/
|
||||
public InputMethodJFrame(String title, InputContext context) {
|
||||
super(title);
|
||||
//InputMethodJFrame never has LookAndFeel decoration
|
||||
if(JFrame.isDefaultLookAndFeelDecorated())
|
||||
{
|
||||
this.setUndecorated(true);
|
||||
this.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
|
||||
}
|
||||
if (context != null) {
|
||||
this.inputContext = context;
|
||||
}
|
||||
setFocusableWindowState(false);
|
||||
}
|
||||
|
||||
public void setInputContext(InputContext inputContext) {
|
||||
this.inputContext = inputContext;
|
||||
}
|
||||
|
||||
public java.awt.im.InputContext getInputContext() {
|
||||
if (inputContext != null) {
|
||||
return inputContext;
|
||||
} else {
|
||||
return super.getInputContext();
|
||||
}
|
||||
}
|
||||
|
||||
// Proclaim serial compatibility with 1.7.0
|
||||
private static final long serialVersionUID = -4705856747771842549L;
|
||||
}
|
||||
171
jdkSrc/jdk8/sun/awt/im/InputMethodLocator.java
Normal file
171
jdkSrc/jdk8/sun/awt/im/InputMethodLocator.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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.im;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.im.spi.InputMethodDescriptor;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Provides complete information to make and handle the selection
|
||||
* of an input method and a locale. Immutable class.
|
||||
*/
|
||||
final class InputMethodLocator {
|
||||
|
||||
private InputMethodDescriptor descriptor;
|
||||
|
||||
// Currently `loader' is always the class loader for a
|
||||
// descriptor. `loader' is provided for future extensions to be
|
||||
// able to load input methods from somewhere else, and to support
|
||||
// per input method name space.
|
||||
private ClassLoader loader;
|
||||
|
||||
private Locale locale;
|
||||
|
||||
InputMethodLocator(InputMethodDescriptor descriptor, ClassLoader loader, Locale locale) {
|
||||
if (descriptor == null) {
|
||||
throw new NullPointerException("descriptor can't be null");
|
||||
}
|
||||
this.descriptor = descriptor;
|
||||
this.loader = loader;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if (other == null || this.getClass() != other.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InputMethodLocator otherLocator = (InputMethodLocator) other;
|
||||
if (!descriptor.getClass().equals(otherLocator.descriptor.getClass())) {
|
||||
return false;
|
||||
}
|
||||
if (loader == null && otherLocator.loader != null
|
||||
|| loader != null && !loader.equals(otherLocator.loader)) {
|
||||
return false;
|
||||
}
|
||||
if (locale == null && otherLocator.locale != null
|
||||
|| locale != null && !locale.equals(otherLocator.locale)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = descriptor.hashCode();
|
||||
if (loader != null) {
|
||||
result |= loader.hashCode() << 10;
|
||||
}
|
||||
if (locale != null) {
|
||||
result |= locale.hashCode() << 20;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
InputMethodDescriptor getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
ClassLoader getClassLoader() {
|
||||
return loader;
|
||||
}
|
||||
|
||||
Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether support for locale is available from
|
||||
* the input method.
|
||||
*/
|
||||
boolean isLocaleAvailable(Locale locale) {
|
||||
try {
|
||||
Locale[] locales = descriptor.getAvailableLocales();
|
||||
for (int i = 0; i < locales.length; i++) {
|
||||
if (locales[i].equals(locale)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (AWTException e) {
|
||||
// treat this as no locale available
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input method locator that has locale forLocale,
|
||||
* but otherwise the same data as this locator. Does not
|
||||
* check whether the input method actually supports forLocale -
|
||||
* use {@link #isLocaleAvailable} for that.
|
||||
*/
|
||||
InputMethodLocator deriveLocator(Locale forLocale) {
|
||||
if (forLocale == locale) {
|
||||
return this;
|
||||
} else {
|
||||
return new InputMethodLocator(descriptor, loader, forLocale);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this and other describe the same input method
|
||||
* engine, ignoring the locale setting.
|
||||
*/
|
||||
boolean sameInputMethod(InputMethodLocator other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!descriptor.getClass().equals(other.descriptor.getClass())) {
|
||||
return false;
|
||||
}
|
||||
if (loader == null && other.loader != null
|
||||
|| loader != null && !loader.equals(other.loader)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string that can be used as an action command string.
|
||||
* The first part of the string identifies the input method; it does
|
||||
* not include '\n'. If getLocale is not null, getLocale().toString()
|
||||
* is appended, separated by '\n'.
|
||||
*/
|
||||
String getActionCommandString() {
|
||||
String inputMethodString = descriptor.getClass().getName();
|
||||
if (locale == null) {
|
||||
return inputMethodString;
|
||||
} else {
|
||||
return inputMethodString + "\n" + locale.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
231
jdkSrc/jdk8/sun/awt/im/InputMethodManager.java
Normal file
231
jdkSrc/jdk8/sun/awt/im/InputMethodManager.java
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, 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.im;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.CheckboxMenuItem;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Frame;
|
||||
import java.awt.PopupMenu;
|
||||
import java.awt.Menu;
|
||||
import java.awt.MenuItem;
|
||||
import java.awt.Toolkit;
|
||||
import sun.awt.AppContext;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.InvocationEvent;
|
||||
import java.awt.im.spi.InputMethodDescriptor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Vector;
|
||||
import java.util.Set;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
import sun.awt.InputMethodSupport;
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
/**
|
||||
* <code>InputMethodManager</code> is an abstract class that manages the input
|
||||
* method environment of JVM. There is only one <code>InputMethodManager</code>
|
||||
* instance in JVM that is executed under a separate daemon thread.
|
||||
* <code>InputMethodManager</code> performs the following:
|
||||
* <UL>
|
||||
* <LI>
|
||||
* Keeps track of the current input context.</LI>
|
||||
*
|
||||
* <LI>
|
||||
* Provides a user interface to switch input methods and notifies the current
|
||||
* input context about changes made from the user interface.</LI>
|
||||
* </UL>
|
||||
*
|
||||
* The mechanism for supporting input method switch is as follows. (Note that
|
||||
* this may change in future releases.)
|
||||
*
|
||||
* <UL>
|
||||
* <LI>
|
||||
* One way is to use platform-dependent window manager's menu (known as the <I>Window
|
||||
* menu </I>in Motif and the <I>System menu</I> or <I>Control menu</I> in
|
||||
* Win32) on each window which is popped up by clicking the left top box of
|
||||
* a window (known as <I>Window menu button</I> in Motif and <I>System menu
|
||||
* button</I> in Win32). This happens to be common in both Motif and Win32.</LI>
|
||||
*
|
||||
* <LI>
|
||||
* When more than one input method descriptor can be found or the only input
|
||||
* method descriptor found supports multiple locales, a menu item
|
||||
* is added to the window (manager) menu. This item label is obtained invoking
|
||||
* <code>getTriggerMenuString()</code>. If null is returned by this method, it
|
||||
* means that there is only input method or none in the environment. Frame and Dialog
|
||||
* invoke this method.</LI>
|
||||
*
|
||||
* <LI>
|
||||
* This menu item means a trigger switch to the user to pop up a selection
|
||||
* menu.</LI>
|
||||
*
|
||||
* <LI>
|
||||
* When the menu item of the window (manager) menu has been selected by the
|
||||
* user, Frame/Dialog invokes <code>notifyChangeRequest()</code> to notify
|
||||
* <code>InputMethodManager</code> that the user wants to switch input methods.</LI>
|
||||
*
|
||||
* <LI>
|
||||
* <code>InputMethodManager</code> displays a pop-up menu to choose an input method.</LI>
|
||||
*
|
||||
* <LI>
|
||||
* <code>InputMethodManager</code> notifies the current <code>InputContext</code> of
|
||||
* the selected <code>InputMethod</code>.</LI>
|
||||
* </UL>
|
||||
*
|
||||
* <UL>
|
||||
* <LI>
|
||||
* The other way is to use user-defined hot key combination to show the pop-up menu to
|
||||
* choose an input method. This is useful for the platforms which do not provide a
|
||||
* way to add a menu item in the window (manager) menu.</LI>
|
||||
*
|
||||
* <LI>
|
||||
* When the hot key combination is typed by the user, the component which has the input
|
||||
* focus invokes <code>notifyChangeRequestByHotKey()</code> to notify
|
||||
* <code>InputMethodManager</code> that the user wants to switch input methods.</LI>
|
||||
*
|
||||
* <LI>
|
||||
* This results in a popup menu and notification to the current input context,
|
||||
* as above.</LI>
|
||||
* </UL>
|
||||
*
|
||||
* @see java.awt.im.spi.InputMethod
|
||||
* @see sun.awt.im.InputContext
|
||||
* @see sun.awt.im.InputMethodAdapter
|
||||
* @author JavaSoft International
|
||||
*/
|
||||
|
||||
public abstract class InputMethodManager {
|
||||
|
||||
/**
|
||||
* InputMethodManager thread name
|
||||
*/
|
||||
private static final String threadName = "AWT-InputMethodManager";
|
||||
|
||||
/**
|
||||
* Object for global locking
|
||||
*/
|
||||
private static final Object LOCK = new Object();
|
||||
|
||||
/**
|
||||
* The InputMethodManager instance
|
||||
*/
|
||||
private static InputMethodManager inputMethodManager;
|
||||
|
||||
/**
|
||||
* Returns the instance of InputMethodManager. This method creates
|
||||
* the instance that is unique in the Java VM if it has not been
|
||||
* created yet.
|
||||
*
|
||||
* @return the InputMethodManager instance
|
||||
*/
|
||||
public static final InputMethodManager getInstance() {
|
||||
if (inputMethodManager != null) {
|
||||
return inputMethodManager;
|
||||
}
|
||||
synchronized(LOCK) {
|
||||
if (inputMethodManager == null) {
|
||||
ExecutableInputMethodManager imm = new ExecutableInputMethodManager();
|
||||
|
||||
// Initialize the input method manager and start a
|
||||
// daemon thread if the user has multiple input methods
|
||||
// to choose from. Otherwise, just keep the instance.
|
||||
if (imm.hasMultipleInputMethods()) {
|
||||
imm.initialize();
|
||||
Thread immThread = new Thread(imm, threadName);
|
||||
immThread.setDaemon(true);
|
||||
immThread.setPriority(Thread.NORM_PRIORITY + 1);
|
||||
immThread.start();
|
||||
}
|
||||
inputMethodManager = imm;
|
||||
}
|
||||
}
|
||||
return inputMethodManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string for the trigger menu item that should be added to
|
||||
* the window manager menu. If no need to display the trigger menu
|
||||
* item, null is returned.
|
||||
*/
|
||||
public abstract String getTriggerMenuString();
|
||||
|
||||
/**
|
||||
* Notifies InputMethodManager that input method change has been
|
||||
* requested by the user. This notification triggers a popup menu
|
||||
* for user selection.
|
||||
*
|
||||
* @param comp Component that has accepted the change
|
||||
* request. This component has to be a Frame or Dialog.
|
||||
*/
|
||||
public abstract void notifyChangeRequest(Component comp);
|
||||
|
||||
/**
|
||||
* Notifies InputMethodManager that input method change has been
|
||||
* requested by the user using the hot key combination. This
|
||||
* notification triggers a popup menu for user selection.
|
||||
*
|
||||
* @param comp Component that has accepted the change
|
||||
* request. This component has the input focus.
|
||||
*/
|
||||
public abstract void notifyChangeRequestByHotKey(Component comp);
|
||||
|
||||
/**
|
||||
* Sets the current input context so that it will be notified
|
||||
* of input method changes initiated from the user interface.
|
||||
* Set to real input context when activating; to null when
|
||||
* deactivating.
|
||||
*/
|
||||
abstract void setInputContext(InputContext inputContext);
|
||||
|
||||
/**
|
||||
* Tries to find an input method locator for the given locale.
|
||||
* Returns null if no available input method locator supports
|
||||
* the locale.
|
||||
*/
|
||||
abstract InputMethodLocator findInputMethod(Locale forLocale);
|
||||
|
||||
/**
|
||||
* Gets the default keyboard locale of the underlying operating system.
|
||||
*/
|
||||
abstract Locale getDefaultKeyboardLocale();
|
||||
|
||||
/**
|
||||
* Returns whether multiple input methods are available or not
|
||||
*/
|
||||
abstract boolean hasMultipleInputMethods();
|
||||
|
||||
}
|
||||
275
jdkSrc/jdk8/sun/awt/im/InputMethodPopupMenu.java
Normal file
275
jdkSrc/jdk8/sun/awt/im/InputMethodPopupMenu.java
Normal file
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2007, 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.im;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.CheckboxMenuItem;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.PopupMenu;
|
||||
import java.awt.Menu;
|
||||
import java.awt.MenuItem;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.im.spi.InputMethodDescriptor;
|
||||
import java.util.Locale;
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
|
||||
/**
|
||||
* <code>InputMethodPopupMenu</code> provides the popup selection menu
|
||||
*/
|
||||
|
||||
abstract class InputMethodPopupMenu implements ActionListener {
|
||||
|
||||
// Factory method to provide the menu, depending on the client, i.e.,
|
||||
// provide Swing popup menu if client is a swing app, otherwise AWT popup
|
||||
// is created.
|
||||
static InputMethodPopupMenu getInstance(Component client, String title) {
|
||||
if ((client instanceof JFrame) ||
|
||||
(client instanceof JDialog)) {
|
||||
return new JInputMethodPopupMenu(title);
|
||||
} else {
|
||||
return new AWTInputMethodPopupMenu(title);
|
||||
}
|
||||
}
|
||||
|
||||
abstract void show(Component c, int x, int y);
|
||||
|
||||
abstract void removeAll();
|
||||
|
||||
abstract void addSeparator();
|
||||
|
||||
abstract void addToComponent(Component c);
|
||||
|
||||
abstract Object createSubmenu(String label);
|
||||
|
||||
abstract void add(Object menuItem);
|
||||
|
||||
abstract void addMenuItem(String label, String command, String currentSelection);
|
||||
|
||||
abstract void addMenuItem(Object targetMenu, String label, String command,
|
||||
String currentSelection);
|
||||
|
||||
void addOneInputMethodToMenu(InputMethodLocator locator, String currentSelection) {
|
||||
InputMethodDescriptor descriptor = locator.getDescriptor();
|
||||
String label = descriptor.getInputMethodDisplayName(null, Locale.getDefault());
|
||||
String command = locator.getActionCommandString();
|
||||
Locale[] locales = null;
|
||||
int localeCount;
|
||||
try {
|
||||
locales = descriptor.getAvailableLocales();
|
||||
localeCount = locales.length;
|
||||
} catch (AWTException e) {
|
||||
// ??? should have better error handling -
|
||||
// tell user what happened, then remove this input method from the list.
|
||||
// For the time being, just show it disabled.
|
||||
localeCount = 0;
|
||||
}
|
||||
if (localeCount == 0) {
|
||||
// could be IIIMP adapter which has lost its connection
|
||||
addMenuItem(label, null, currentSelection);
|
||||
} else if (localeCount == 1) {
|
||||
if (descriptor.hasDynamicLocaleList()) {
|
||||
// try to make sure that what the user sees and what
|
||||
// we eventually select is consistent even if the locale
|
||||
// list changes in the meantime
|
||||
label = descriptor.getInputMethodDisplayName(locales[0], Locale.getDefault());
|
||||
command = locator.deriveLocator(locales[0]).getActionCommandString();
|
||||
}
|
||||
addMenuItem(label, command, currentSelection);
|
||||
} else {
|
||||
Object submenu = createSubmenu(label);
|
||||
add(submenu);
|
||||
for (int j = 0; j < localeCount; j++) {
|
||||
Locale locale = locales[j];
|
||||
String subLabel = getLocaleName(locale);
|
||||
String subCommand = locator.deriveLocator(locale).getActionCommandString();
|
||||
addMenuItem(submenu, subLabel, subCommand, currentSelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether command indicates the same input method as currentSelection,
|
||||
* taking into account that command may not specify a locale where currentSelection does.
|
||||
*/
|
||||
static boolean isSelected(String command, String currentSelection) {
|
||||
if (command == null || currentSelection == null) {
|
||||
return false;
|
||||
}
|
||||
if (command.equals(currentSelection)) {
|
||||
return true;
|
||||
}
|
||||
// currentSelection may indicate a locale where command does not
|
||||
int index = currentSelection.indexOf('\n');
|
||||
if (index != -1 && currentSelection.substring(0, index).equals(command)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a localized locale name for input methods with the
|
||||
* given locale. It falls back to Locale.getDisplayName() and
|
||||
* then to Locale.toString() if no localized locale name is found.
|
||||
*
|
||||
* @param locale Locale for which localized locale name is obtained
|
||||
*/
|
||||
String getLocaleName(Locale locale) {
|
||||
String localeString = locale.toString();
|
||||
String localeName = Toolkit.getProperty("AWT.InputMethodLanguage." + localeString, null);
|
||||
if (localeName == null) {
|
||||
localeName = locale.getDisplayName();
|
||||
if (localeName == null || localeName.length() == 0)
|
||||
localeName = localeString;
|
||||
}
|
||||
return localeName;
|
||||
}
|
||||
|
||||
// ActionListener implementation
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
String choice = event.getActionCommand();
|
||||
((ExecutableInputMethodManager)InputMethodManager.getInstance()).changeInputMethod(choice);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class JInputMethodPopupMenu extends InputMethodPopupMenu {
|
||||
static JPopupMenu delegate = null;
|
||||
|
||||
JInputMethodPopupMenu(String title) {
|
||||
synchronized (this) {
|
||||
if (delegate == null) {
|
||||
delegate = new JPopupMenu(title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void show(Component c, int x, int y) {
|
||||
delegate.show(c, x, y);
|
||||
}
|
||||
|
||||
void removeAll() {
|
||||
delegate.removeAll();
|
||||
}
|
||||
|
||||
void addSeparator() {
|
||||
delegate.addSeparator();
|
||||
}
|
||||
|
||||
void addToComponent(Component c) {
|
||||
}
|
||||
|
||||
Object createSubmenu(String label) {
|
||||
return new JMenu(label);
|
||||
}
|
||||
|
||||
void add(Object menuItem) {
|
||||
delegate.add((JMenuItem)menuItem);
|
||||
}
|
||||
|
||||
void addMenuItem(String label, String command, String currentSelection) {
|
||||
addMenuItem(delegate, label, command, currentSelection);
|
||||
}
|
||||
|
||||
void addMenuItem(Object targetMenu, String label, String command, String currentSelection) {
|
||||
JMenuItem menuItem;
|
||||
if (isSelected(command, currentSelection)) {
|
||||
menuItem = new JCheckBoxMenuItem(label, true);
|
||||
} else {
|
||||
menuItem = new JMenuItem(label);
|
||||
}
|
||||
menuItem.setActionCommand(command);
|
||||
menuItem.addActionListener(this);
|
||||
menuItem.setEnabled(command != null);
|
||||
if (targetMenu instanceof JMenu) {
|
||||
((JMenu)targetMenu).add(menuItem);
|
||||
} else {
|
||||
((JPopupMenu)targetMenu).add(menuItem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AWTInputMethodPopupMenu extends InputMethodPopupMenu {
|
||||
static PopupMenu delegate = null;
|
||||
|
||||
AWTInputMethodPopupMenu(String title) {
|
||||
synchronized (this) {
|
||||
if (delegate == null) {
|
||||
delegate = new PopupMenu(title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void show(Component c, int x, int y) {
|
||||
delegate.show(c, x, y);
|
||||
}
|
||||
|
||||
void removeAll() {
|
||||
delegate.removeAll();
|
||||
}
|
||||
|
||||
void addSeparator() {
|
||||
delegate.addSeparator();
|
||||
}
|
||||
|
||||
void addToComponent(Component c) {
|
||||
c.add(delegate);
|
||||
}
|
||||
|
||||
Object createSubmenu(String label) {
|
||||
return new Menu(label);
|
||||
}
|
||||
|
||||
void add(Object menuItem) {
|
||||
delegate.add((MenuItem)menuItem);
|
||||
}
|
||||
|
||||
void addMenuItem(String label, String command, String currentSelection) {
|
||||
addMenuItem(delegate, label, command, currentSelection);
|
||||
}
|
||||
|
||||
void addMenuItem(Object targetMenu, String label, String command, String currentSelection) {
|
||||
MenuItem menuItem;
|
||||
if (isSelected(command, currentSelection)) {
|
||||
menuItem = new CheckboxMenuItem(label, true);
|
||||
} else {
|
||||
menuItem = new MenuItem(label);
|
||||
}
|
||||
menuItem.setActionCommand(command);
|
||||
menuItem.addActionListener(this);
|
||||
menuItem.setEnabled(command != null);
|
||||
((Menu)targetMenu).add(menuItem);
|
||||
}
|
||||
}
|
||||
42
jdkSrc/jdk8/sun/awt/im/InputMethodWindow.java
Normal file
42
jdkSrc/jdk8/sun/awt/im/InputMethodWindow.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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.im;
|
||||
|
||||
/**
|
||||
* Interface for input method windows that need special handling
|
||||
* by input method window.
|
||||
*
|
||||
*/
|
||||
public interface InputMethodWindow {
|
||||
|
||||
/**
|
||||
* Sets the input context that this input method window is attached to,
|
||||
* null to unattach the window.
|
||||
* @see java.awt.im.spi.InputMethodContext#createInputMethodWindow
|
||||
*/
|
||||
public void setInputContext(InputContext inputContext);
|
||||
|
||||
}
|
||||
67
jdkSrc/jdk8/sun/awt/im/SimpleInputMethodWindow.java
Normal file
67
jdkSrc/jdk8/sun/awt/im/SimpleInputMethodWindow.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, 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.im;
|
||||
|
||||
import java.awt.Frame;
|
||||
|
||||
/**
|
||||
* Implements a simple input method window that provides the minimal
|
||||
* functionality as specified in
|
||||
* {@link java.awt.im.spi.InputMethodContext#createInputMethodWindow}.
|
||||
*
|
||||
*/
|
||||
public class SimpleInputMethodWindow
|
||||
extends Frame
|
||||
implements InputMethodWindow {
|
||||
|
||||
InputContext inputContext = null;
|
||||
|
||||
/**
|
||||
* Constructs a simple input method window.
|
||||
*/
|
||||
public SimpleInputMethodWindow(String title, InputContext context) {
|
||||
super(title);
|
||||
if (context != null) {
|
||||
this.inputContext = context;
|
||||
}
|
||||
setFocusableWindowState(false);
|
||||
}
|
||||
|
||||
public void setInputContext(InputContext inputContext) {
|
||||
this.inputContext = inputContext;
|
||||
}
|
||||
|
||||
public java.awt.im.InputContext getInputContext() {
|
||||
if (inputContext != null) {
|
||||
return inputContext;
|
||||
} else {
|
||||
return super.getInputContext();
|
||||
}
|
||||
}
|
||||
|
||||
// Proclaim serial compatibility with 1.7.0
|
||||
private static final long serialVersionUID = 5093376647036461555L;
|
||||
}
|
||||
122
jdkSrc/jdk8/sun/awt/image/AbstractMultiResolutionImage.java
Normal file
122
jdkSrc/jdk8/sun/awt/image/AbstractMultiResolutionImage.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 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.image;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* This class provides default implementations for the
|
||||
* <code>MultiResolutionImage</code> interface. The developer needs only
|
||||
* to subclass this abstract class and define the <code>getResolutionVariant</code>,
|
||||
* <code>getResolutionVariants</code>, and <code>getBaseImage</code> methods.
|
||||
*
|
||||
*
|
||||
* For example,
|
||||
* {@code
|
||||
* public class CustomMultiResolutionImage extends AbstractMultiResolutionImage {
|
||||
*
|
||||
* int baseImageIndex;
|
||||
* Image[] resolutionVariants;
|
||||
*
|
||||
* public CustomMultiResolutionImage(int baseImageIndex,
|
||||
* Image... resolutionVariants) {
|
||||
* this.baseImageIndex = baseImageIndex;
|
||||
* this.resolutionVariants = resolutionVariants;
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public Image getResolutionVariant(float logicalDPIX, float logicalDPIY,
|
||||
* float baseImageWidth, float baseImageHeight,
|
||||
* float destImageWidth, float destImageHeight) {
|
||||
* // return a resolution variant based on the given logical DPI,
|
||||
* // base image size, or destination image size
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public List<Image> getResolutionVariants() {
|
||||
* return Arrays.asList(resolutionVariants);
|
||||
* }
|
||||
*
|
||||
* protected Image getBaseImage() {
|
||||
* return resolutionVariants[baseImageIndex];
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @see java.awt.Image
|
||||
* @see java.awt.image.MultiResolutionImage
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractMultiResolutionImage extends java.awt.Image
|
||||
implements MultiResolutionImage {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public int getWidth(ImageObserver observer) {
|
||||
return getBaseImage().getWidth(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public int getHeight(ImageObserver observer) {
|
||||
return getBaseImage().getHeight(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public ImageProducer getSource() {
|
||||
return getBaseImage().getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public Graphics getGraphics() {
|
||||
return getBaseImage().getGraphics();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public Object getProperty(String name, ImageObserver observer) {
|
||||
return getBaseImage().getProperty(name, observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return base image
|
||||
*/
|
||||
protected abstract Image getBaseImage();
|
||||
}
|
||||
31
jdkSrc/jdk8/sun/awt/image/BadDepthException.java
Normal file
31
jdkSrc/jdk8/sun/awt/image/BadDepthException.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 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.image;
|
||||
|
||||
public class BadDepthException extends Exception {
|
||||
public BadDepthException() {
|
||||
}
|
||||
}
|
||||
422
jdkSrc/jdk8/sun/awt/image/BufImgSurfaceData.java
Normal file
422
jdkSrc/jdk8/sun/awt/image/BufImgSurfaceData.java
Normal file
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2018, 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.image;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import sun.java2d.loops.RenderLoops;
|
||||
|
||||
|
||||
public class BufImgSurfaceData extends SurfaceData {
|
||||
BufferedImage bufImg;
|
||||
private BufferedImageGraphicsConfig graphicsConfig;
|
||||
RenderLoops solidloops;
|
||||
|
||||
private static native void initIDs(Class ICM, Class ICMColorData);
|
||||
|
||||
private static final int DCM_RGBX_RED_MASK = 0xff000000;
|
||||
private static final int DCM_RGBX_GREEN_MASK = 0x00ff0000;
|
||||
private static final int DCM_RGBX_BLUE_MASK = 0x0000ff00;
|
||||
private static final int DCM_555X_RED_MASK = 0xF800;
|
||||
private static final int DCM_555X_GREEN_MASK = 0x07C0;
|
||||
private static final int DCM_555X_BLUE_MASK = 0x003E;
|
||||
private static final int DCM_4444_RED_MASK = 0x0f00;
|
||||
private static final int DCM_4444_GREEN_MASK = 0x00f0;
|
||||
private static final int DCM_4444_BLUE_MASK = 0x000f;
|
||||
private static final int DCM_4444_ALPHA_MASK = 0xf000;
|
||||
private static final int DCM_ARGBBM_ALPHA_MASK = 0x01000000;
|
||||
private static final int DCM_ARGBBM_RED_MASK = 0x00ff0000;
|
||||
private static final int DCM_ARGBBM_GREEN_MASK = 0x0000ff00;
|
||||
private static final int DCM_ARGBBM_BLUE_MASK = 0x000000ff;
|
||||
|
||||
static {
|
||||
initIDs(IndexColorModel.class, ICMColorData.class);
|
||||
}
|
||||
|
||||
public static SurfaceData createData(BufferedImage bufImg) {
|
||||
if (bufImg == null) {
|
||||
throw new NullPointerException("BufferedImage cannot be null");
|
||||
}
|
||||
SurfaceData sData;
|
||||
ColorModel cm = bufImg.getColorModel();
|
||||
int type = bufImg.getType();
|
||||
// REMIND: Check the image type and pick an appropriate subclass
|
||||
switch (type) {
|
||||
case BufferedImage.TYPE_INT_BGR:
|
||||
sData = createDataIC(bufImg, SurfaceType.IntBgr);
|
||||
break;
|
||||
case BufferedImage.TYPE_INT_RGB:
|
||||
sData = createDataIC(bufImg, SurfaceType.IntRgb);
|
||||
break;
|
||||
case BufferedImage.TYPE_INT_ARGB:
|
||||
sData = createDataIC(bufImg, SurfaceType.IntArgb);
|
||||
break;
|
||||
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||||
sData = createDataIC(bufImg, SurfaceType.IntArgbPre);
|
||||
break;
|
||||
case BufferedImage.TYPE_3BYTE_BGR:
|
||||
sData = createDataBC(bufImg, SurfaceType.ThreeByteBgr, 2);
|
||||
break;
|
||||
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||
sData = createDataBC(bufImg, SurfaceType.FourByteAbgr, 3);
|
||||
break;
|
||||
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||
sData = createDataBC(bufImg, SurfaceType.FourByteAbgrPre, 3);
|
||||
break;
|
||||
case BufferedImage.TYPE_USHORT_565_RGB:
|
||||
sData = createDataSC(bufImg, SurfaceType.Ushort565Rgb, null);
|
||||
break;
|
||||
case BufferedImage.TYPE_USHORT_555_RGB:
|
||||
sData = createDataSC(bufImg, SurfaceType.Ushort555Rgb, null);
|
||||
break;
|
||||
case BufferedImage.TYPE_BYTE_INDEXED:
|
||||
{
|
||||
SurfaceType sType;
|
||||
switch (cm.getTransparency()) {
|
||||
case OPAQUE:
|
||||
if (isOpaqueGray((IndexColorModel)cm)) {
|
||||
sType = SurfaceType.Index8Gray;
|
||||
} else {
|
||||
sType = SurfaceType.ByteIndexedOpaque;
|
||||
}
|
||||
break;
|
||||
case BITMASK:
|
||||
sType = SurfaceType.ByteIndexedBm;
|
||||
break;
|
||||
case TRANSLUCENT:
|
||||
sType = SurfaceType.ByteIndexed;
|
||||
break;
|
||||
default:
|
||||
throw new InternalError("Unrecognized transparency");
|
||||
}
|
||||
sData = createDataBC(bufImg, sType, 0);
|
||||
}
|
||||
break;
|
||||
case BufferedImage.TYPE_BYTE_GRAY:
|
||||
sData = createDataBC(bufImg, SurfaceType.ByteGray, 0);
|
||||
break;
|
||||
case BufferedImage.TYPE_USHORT_GRAY:
|
||||
sData = createDataSC(bufImg, SurfaceType.UshortGray, null);
|
||||
break;
|
||||
case BufferedImage.TYPE_BYTE_BINARY:
|
||||
{
|
||||
SurfaceType sType;
|
||||
SampleModel sm = bufImg.getRaster().getSampleModel();
|
||||
switch (sm.getSampleSize(0)) {
|
||||
case 1:
|
||||
sType = SurfaceType.ByteBinary1Bit;
|
||||
break;
|
||||
case 2:
|
||||
sType = SurfaceType.ByteBinary2Bit;
|
||||
break;
|
||||
case 4:
|
||||
sType = SurfaceType.ByteBinary4Bit;
|
||||
break;
|
||||
default:
|
||||
throw new InternalError("Unrecognized pixel size");
|
||||
}
|
||||
sData = createDataBP(bufImg, sType);
|
||||
}
|
||||
break;
|
||||
case BufferedImage.TYPE_CUSTOM:
|
||||
default:
|
||||
{
|
||||
Raster raster = bufImg.getRaster();
|
||||
int numBands = raster.getNumBands();
|
||||
if (raster instanceof IntegerComponentRaster &&
|
||||
raster.getNumDataElements() == 1 &&
|
||||
((IntegerComponentRaster)raster).getPixelStride() == 1)
|
||||
{
|
||||
SurfaceType sType = SurfaceType.AnyInt;
|
||||
if (cm instanceof DirectColorModel) {
|
||||
DirectColorModel dcm = (DirectColorModel) cm;
|
||||
int aMask = dcm.getAlphaMask();
|
||||
int rMask = dcm.getRedMask();
|
||||
int gMask = dcm.getGreenMask();
|
||||
int bMask = dcm.getBlueMask();
|
||||
if (numBands == 3 &&
|
||||
aMask == 0 &&
|
||||
rMask == DCM_RGBX_RED_MASK &&
|
||||
gMask == DCM_RGBX_GREEN_MASK &&
|
||||
bMask == DCM_RGBX_BLUE_MASK)
|
||||
{
|
||||
sType = SurfaceType.IntRgbx;
|
||||
} else if (numBands == 4 &&
|
||||
aMask == DCM_ARGBBM_ALPHA_MASK &&
|
||||
rMask == DCM_ARGBBM_RED_MASK &&
|
||||
gMask == DCM_ARGBBM_GREEN_MASK &&
|
||||
bMask == DCM_ARGBBM_BLUE_MASK)
|
||||
{
|
||||
sType = SurfaceType.IntArgbBm;
|
||||
} else {
|
||||
sType = SurfaceType.AnyDcm;
|
||||
}
|
||||
}
|
||||
sData = createDataIC(bufImg, sType);
|
||||
break;
|
||||
} else if (raster instanceof ShortComponentRaster &&
|
||||
raster.getNumDataElements() == 1 &&
|
||||
((ShortComponentRaster)raster).getPixelStride() == 1)
|
||||
{
|
||||
SurfaceType sType = SurfaceType.AnyShort;
|
||||
IndexColorModel icm = null;
|
||||
if (cm instanceof DirectColorModel) {
|
||||
DirectColorModel dcm = (DirectColorModel) cm;
|
||||
int aMask = dcm.getAlphaMask();
|
||||
int rMask = dcm.getRedMask();
|
||||
int gMask = dcm.getGreenMask();
|
||||
int bMask = dcm.getBlueMask();
|
||||
if (numBands == 3 &&
|
||||
aMask == 0 &&
|
||||
rMask == DCM_555X_RED_MASK &&
|
||||
gMask == DCM_555X_GREEN_MASK &&
|
||||
bMask == DCM_555X_BLUE_MASK)
|
||||
{
|
||||
sType = SurfaceType.Ushort555Rgbx;
|
||||
} else
|
||||
if (numBands == 4 &&
|
||||
aMask == DCM_4444_ALPHA_MASK &&
|
||||
rMask == DCM_4444_RED_MASK &&
|
||||
gMask == DCM_4444_GREEN_MASK &&
|
||||
bMask == DCM_4444_BLUE_MASK)
|
||||
{
|
||||
sType = SurfaceType.Ushort4444Argb;
|
||||
}
|
||||
} else if (cm instanceof IndexColorModel) {
|
||||
icm = (IndexColorModel)cm;
|
||||
if (icm.getPixelSize() == 12) {
|
||||
if (isOpaqueGray(icm)) {
|
||||
sType = SurfaceType.Index12Gray;
|
||||
} else {
|
||||
sType = SurfaceType.UshortIndexed;
|
||||
}
|
||||
} else {
|
||||
icm = null;
|
||||
}
|
||||
}
|
||||
sData = createDataSC(bufImg, sType, icm);
|
||||
break;
|
||||
}
|
||||
sData = new BufImgSurfaceData(raster.getDataBuffer(),
|
||||
bufImg, SurfaceType.Custom);
|
||||
}
|
||||
break;
|
||||
}
|
||||
((BufImgSurfaceData) sData).initSolidLoops();
|
||||
return sData;
|
||||
}
|
||||
|
||||
public static SurfaceData createData(Raster ras, ColorModel cm) {
|
||||
throw new InternalError("SurfaceData not implemented for Raster/CM");
|
||||
}
|
||||
|
||||
public static SurfaceData createDataIC(BufferedImage bImg,
|
||||
SurfaceType sType) {
|
||||
IntegerComponentRaster icRaster =
|
||||
(IntegerComponentRaster)bImg.getRaster();
|
||||
BufImgSurfaceData bisd =
|
||||
new BufImgSurfaceData(icRaster.getDataBuffer(), bImg, sType);
|
||||
bisd.initRaster(icRaster.getDataStorage(),
|
||||
icRaster.getDataOffset(0) * 4, 0,
|
||||
icRaster.getWidth(),
|
||||
icRaster.getHeight(),
|
||||
icRaster.getPixelStride() * 4,
|
||||
icRaster.getScanlineStride() * 4,
|
||||
null);
|
||||
return bisd;
|
||||
}
|
||||
|
||||
public static SurfaceData createDataSC(BufferedImage bImg,
|
||||
SurfaceType sType,
|
||||
IndexColorModel icm) {
|
||||
ShortComponentRaster scRaster =
|
||||
(ShortComponentRaster)bImg.getRaster();
|
||||
BufImgSurfaceData bisd =
|
||||
new BufImgSurfaceData(scRaster.getDataBuffer(), bImg, sType);
|
||||
bisd.initRaster(scRaster.getDataStorage(),
|
||||
scRaster.getDataOffset(0) * 2, 0,
|
||||
scRaster.getWidth(),
|
||||
scRaster.getHeight(),
|
||||
scRaster.getPixelStride() * 2,
|
||||
scRaster.getScanlineStride() * 2,
|
||||
icm);
|
||||
return bisd;
|
||||
}
|
||||
|
||||
public static SurfaceData createDataBC(BufferedImage bImg,
|
||||
SurfaceType sType,
|
||||
int primaryBank) {
|
||||
ByteComponentRaster bcRaster =
|
||||
(ByteComponentRaster)bImg.getRaster();
|
||||
BufImgSurfaceData bisd =
|
||||
new BufImgSurfaceData(bcRaster.getDataBuffer(), bImg, sType);
|
||||
ColorModel cm = bImg.getColorModel();
|
||||
IndexColorModel icm = ((cm instanceof IndexColorModel)
|
||||
? (IndexColorModel) cm
|
||||
: null);
|
||||
bisd.initRaster(bcRaster.getDataStorage(),
|
||||
bcRaster.getDataOffset(primaryBank), 0,
|
||||
bcRaster.getWidth(),
|
||||
bcRaster.getHeight(),
|
||||
bcRaster.getPixelStride(),
|
||||
bcRaster.getScanlineStride(),
|
||||
icm);
|
||||
return bisd;
|
||||
}
|
||||
|
||||
public static SurfaceData createDataBP(BufferedImage bImg,
|
||||
SurfaceType sType) {
|
||||
BytePackedRaster bpRaster =
|
||||
(BytePackedRaster)bImg.getRaster();
|
||||
BufImgSurfaceData bisd =
|
||||
new BufImgSurfaceData(bpRaster.getDataBuffer(), bImg, sType);
|
||||
ColorModel cm = bImg.getColorModel();
|
||||
IndexColorModel icm = ((cm instanceof IndexColorModel)
|
||||
? (IndexColorModel) cm
|
||||
: null);
|
||||
bisd.initRaster(bpRaster.getDataStorage(),
|
||||
bpRaster.getDataBitOffset() / 8,
|
||||
bpRaster.getDataBitOffset() & 7,
|
||||
bpRaster.getWidth(),
|
||||
bpRaster.getHeight(),
|
||||
0,
|
||||
bpRaster.getScanlineStride(),
|
||||
icm);
|
||||
return bisd;
|
||||
}
|
||||
|
||||
public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
|
||||
if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
|
||||
sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY)
|
||||
{
|
||||
return solidloops;
|
||||
}
|
||||
return super.getRenderLoops(sg2d);
|
||||
}
|
||||
|
||||
public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
|
||||
return bufImg.getRaster();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the native Ops pointer.
|
||||
*/
|
||||
protected native void initRaster(Object theArray,
|
||||
int offset,
|
||||
int bitoffset,
|
||||
int width,
|
||||
int height,
|
||||
int pixStr,
|
||||
int scanStr,
|
||||
IndexColorModel icm);
|
||||
|
||||
public BufImgSurfaceData(DataBuffer db,
|
||||
BufferedImage bufImg, SurfaceType sType)
|
||||
{
|
||||
super(SunWritableRaster.stealTrackable(db),
|
||||
sType, bufImg.getColorModel());
|
||||
this.bufImg = bufImg;
|
||||
}
|
||||
|
||||
protected BufImgSurfaceData(SurfaceType surfaceType, ColorModel cm) {
|
||||
super(surfaceType, cm);
|
||||
}
|
||||
|
||||
public void initSolidLoops() {
|
||||
this.solidloops = getSolidLoops(getSurfaceType());
|
||||
}
|
||||
|
||||
private static final int CACHE_SIZE = 5;
|
||||
private static RenderLoops loopcache[] = new RenderLoops[CACHE_SIZE];
|
||||
private static SurfaceType typecache[] = new SurfaceType[CACHE_SIZE];
|
||||
public static synchronized RenderLoops getSolidLoops(SurfaceType type) {
|
||||
for (int i = CACHE_SIZE - 1; i >= 0; i--) {
|
||||
SurfaceType t = typecache[i];
|
||||
if (t == type) {
|
||||
return loopcache[i];
|
||||
} else if (t == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
RenderLoops l = makeRenderLoops(SurfaceType.OpaqueColor,
|
||||
CompositeType.SrcNoEa,
|
||||
type);
|
||||
System.arraycopy(loopcache, 1, loopcache, 0, CACHE_SIZE-1);
|
||||
System.arraycopy(typecache, 1, typecache, 0, CACHE_SIZE-1);
|
||||
loopcache[CACHE_SIZE - 1] = l;
|
||||
typecache[CACHE_SIZE - 1] = type;
|
||||
return l;
|
||||
}
|
||||
|
||||
public SurfaceData getReplacement() {
|
||||
// BufImgSurfaceData objects should never lose their contents,
|
||||
// so this method should never be called.
|
||||
return restoreContents(bufImg);
|
||||
}
|
||||
|
||||
public synchronized GraphicsConfiguration getDeviceConfiguration() {
|
||||
if (graphicsConfig == null) {
|
||||
graphicsConfig = BufferedImageGraphicsConfig.getConfig(bufImg);
|
||||
}
|
||||
return graphicsConfig;
|
||||
}
|
||||
|
||||
public java.awt.Rectangle getBounds() {
|
||||
return new Rectangle(bufImg.getWidth(), bufImg.getHeight());
|
||||
}
|
||||
|
||||
protected void checkCustomComposite() {
|
||||
// BufferedImages always allow Custom Composite objects since
|
||||
// their pixels are immediately retrievable anyway.
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns destination Image associated with this SurfaceData.
|
||||
*/
|
||||
public Object getDestination() {
|
||||
return bufImg;
|
||||
}
|
||||
|
||||
public static final class ICMColorData {
|
||||
private long pData = 0L;
|
||||
|
||||
private ICMColorData(long pData) {
|
||||
this.pData = pData;
|
||||
}
|
||||
}
|
||||
}
|
||||
69
jdkSrc/jdk8/sun/awt/image/BufImgSurfaceManager.java
Normal file
69
jdkSrc/jdk8/sun/awt/image/BufImgSurfaceManager.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.image;
|
||||
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.ImageCapabilities;
|
||||
import java.awt.image.BufferedImage;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
|
||||
/**
|
||||
* This SurfaceManager variant manages the default (software) surface of a
|
||||
* BufferedImage.
|
||||
* All rendering to the image will use the software surface as the destination.
|
||||
* This is one of the more minimalist implementations of SurfaceManager.
|
||||
*/
|
||||
public class BufImgSurfaceManager extends SurfaceManager {
|
||||
/**
|
||||
* A reference to the BufferedImage whose contents are being managed.
|
||||
*/
|
||||
protected BufferedImage bImg;
|
||||
|
||||
/**
|
||||
* The default (software) surface containing the contents of the
|
||||
* BufferedImage.
|
||||
*/
|
||||
protected SurfaceData sdDefault;
|
||||
|
||||
public BufImgSurfaceManager(BufferedImage bImg) {
|
||||
this.bImg = bImg;
|
||||
this.sdDefault = BufImgSurfaceData.createData(bImg);
|
||||
}
|
||||
|
||||
public SurfaceData getPrimarySurfaceData() {
|
||||
return sdDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from platform-specific SurfaceData objects to attempt to
|
||||
* auto-restore the contents of an accelerated surface that has been lost.
|
||||
*/
|
||||
public SurfaceData restoreContents() {
|
||||
return sdDefault;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user