mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
745 lines
27 KiB
Java
745 lines
27 KiB
Java
![]() |
/*
|
||
|
* This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com>
|
||
|
* Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/)
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* @(#)SunToolkit.java 1.76 03/01/23
|
||
|
*
|
||
|
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
||
|
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||
|
*/
|
||
|
|
||
|
package sun.awt;
|
||
|
|
||
|
import java.awt.*;
|
||
|
import java.awt.dnd.*;
|
||
|
import java.awt.dnd.peer.DragSourceContextPeer;
|
||
|
import java.awt.peer.*;
|
||
|
import java.awt.event.WindowEvent;
|
||
|
import java.awt.im.spi.InputMethodDescriptor;
|
||
|
import java.awt.image.*;
|
||
|
import java.awt.geom.AffineTransform;
|
||
|
import java.io.*;
|
||
|
import java.net.URL;
|
||
|
import java.net.JarURLConnection;
|
||
|
import java.security.AccessController;
|
||
|
import java.util.*;
|
||
|
import sun.misc.SoftCache;
|
||
|
import sun.awt.font.FontDesignMetrics;
|
||
|
import sun.awt.im.InputContext;
|
||
|
import sun.awt.im.SimpleInputMethodWindow;
|
||
|
import sun.awt.image.*;
|
||
|
import sun.awt.font.NativeFontWrapper;
|
||
|
import sun.security.action.GetPropertyAction;
|
||
|
import java.lang.reflect.Constructor;
|
||
|
|
||
|
public abstract class SunToolkit extends Toolkit
|
||
|
implements WindowClosingSupport, WindowClosingListener,
|
||
|
ComponentFactory, InputMethodSupport {
|
||
|
|
||
|
/* Force the debug helper classes to initialize */
|
||
|
{
|
||
|
DebugHelper.init();
|
||
|
}
|
||
|
|
||
|
private static boolean hotjavaUrlCache = false; // REMIND: UGH!!!!!
|
||
|
|
||
|
/* The key to put()/get() the PostEventQueue into/from the AppContext.
|
||
|
*/
|
||
|
private static final String POST_EVENT_QUEUE_KEY = "PostEventQueue";
|
||
|
|
||
|
public SunToolkit() {
|
||
|
/* If awt.threadgroup is set to class name the instance of
|
||
|
* this class is created (should be subclass of ThreadGroup)
|
||
|
* and EventDispatchThread is created inside of it
|
||
|
*
|
||
|
* If loaded class overrides uncaughtException instance
|
||
|
* handles all uncaught exception on EventDispatchThread
|
||
|
*/
|
||
|
ThreadGroup threadGroup = null;
|
||
|
String tgName = System.getProperty("awt.threadgroup", "");
|
||
|
|
||
|
if (tgName.length() != 0) {
|
||
|
try {
|
||
|
Constructor ctor = Class.forName(tgName).
|
||
|
getConstructor(new Class[] {String.class});
|
||
|
threadGroup = (ThreadGroup)ctor.newInstance(new Object[] {"AWT-ThreadGroup"});
|
||
|
} catch (Exception e) {
|
||
|
System.err.println("Failed loading " + tgName + ": " + e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Runnable initEQ = new Runnable() {
|
||
|
public void run () {
|
||
|
EventQueue eventQueue;
|
||
|
|
||
|
String eqName = Toolkit.getProperty("AWT.EventQueueClass",
|
||
|
"java.awt.EventQueue");
|
||
|
|
||
|
try {
|
||
|
eventQueue = (EventQueue)Class.forName(eqName).newInstance();
|
||
|
} catch (Exception e) {
|
||
|
System.err.println("Failed loading " + eqName + ": " + e);
|
||
|
eventQueue = new EventQueue();
|
||
|
}
|
||
|
AppContext appContext = AppContext.getAppContext();
|
||
|
appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue);
|
||
|
|
||
|
PostEventQueue postEventQueue = new PostEventQueue(eventQueue);
|
||
|
appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
if (threadGroup != null) {
|
||
|
Thread eqInitThread = new Thread(threadGroup, initEQ, "EventQueue-Init");
|
||
|
eqInitThread.start();
|
||
|
try {
|
||
|
eqInitThread.join();
|
||
|
} catch (InterruptedException e) {
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
} else {
|
||
|
initEQ.run();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public abstract WindowPeer createWindow(Window target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract FramePeer createFrame(Frame target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract DialogPeer createDialog(Dialog target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract ButtonPeer createButton(Button target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract TextFieldPeer createTextField(TextField target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract ChoicePeer createChoice(Choice target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract LabelPeer createLabel(Label target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract ListPeer createList(java.awt.List target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract CheckboxPeer createCheckbox(Checkbox target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract ScrollbarPeer createScrollbar(Scrollbar target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract ScrollPanePeer createScrollPane(ScrollPane target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract TextAreaPeer createTextArea(TextArea target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract FileDialogPeer createFileDialog(FileDialog target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract MenuBarPeer createMenuBar(MenuBar target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract MenuPeer createMenu(Menu target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract PopupMenuPeer createPopupMenu(PopupMenu target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract MenuItemPeer createMenuItem(MenuItem target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract CheckboxMenuItemPeer createCheckboxMenuItem(
|
||
|
CheckboxMenuItem target)
|
||
|
throws HeadlessException;
|
||
|
|
||
|
public abstract DragSourceContextPeer createDragSourceContextPeer(
|
||
|
DragGestureEvent dge)
|
||
|
throws InvalidDnDOperationException;
|
||
|
|
||
|
public abstract FontPeer getFontPeer(String name, int style);
|
||
|
|
||
|
public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
|
||
|
throws AWTException;
|
||
|
|
||
|
/*
|
||
|
* Create a new AppContext, along with its EventQueue, for a
|
||
|
* new ThreadGroup. Browser code, for example, would use this
|
||
|
* method to create an AppContext & EventQueue for an Applet.
|
||
|
*/
|
||
|
public static AppContext createNewAppContext() {
|
||
|
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
|
||
|
EventQueue eventQueue;
|
||
|
String eqName = Toolkit.getProperty("AWT.EventQueueClass",
|
||
|
"java.awt.EventQueue");
|
||
|
try {
|
||
|
eventQueue = (EventQueue)Class.forName(eqName).newInstance();
|
||
|
} catch (Exception e) {
|
||
|
System.err.println("Failed loading " + eqName + ": " + e);
|
||
|
eventQueue = new EventQueue();
|
||
|
}
|
||
|
AppContext appContext = new AppContext(threadGroup);
|
||
|
appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue);
|
||
|
|
||
|
PostEventQueue postEventQueue = new PostEventQueue(eventQueue);
|
||
|
appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue);
|
||
|
|
||
|
return appContext;
|
||
|
}
|
||
|
|
||
|
private static native Object getPrivateKey(Object o);
|
||
|
|
||
|
static native void wakeupEventQueue(EventQueue q, boolean isShutdown);
|
||
|
|
||
|
// mapping of components to peers, Hashtable<Component,Peer>
|
||
|
protected static final Hashtable peerMap =
|
||
|
AWTAutoShutdown.getInstance().getPeerMap();
|
||
|
|
||
|
/*
|
||
|
* Fetch the peer associated with the given target (as specified
|
||
|
* in the peer creation method). This can be used to determine
|
||
|
* things like what the parent peer is. If the target is null
|
||
|
* or the target can't be found (either because the a peer was
|
||
|
* never created for it or the peer was disposed), a null will
|
||
|
* be returned.
|
||
|
*/
|
||
|
protected static Object targetToPeer(Object target) {
|
||
|
if (target != null && !GraphicsEnvironment.isHeadless()) {
|
||
|
return peerMap.get(getPrivateKey(target));
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
protected static void targetCreatedPeer(Object target, Object peer) {
|
||
|
if (target != null && peer != null &&
|
||
|
!GraphicsEnvironment.isHeadless()) {
|
||
|
peerMap.put(getPrivateKey(target), peer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected static void targetDisposedPeer(Object target, Object peer) {
|
||
|
if (target != null && peer != null &&
|
||
|
!GraphicsEnvironment.isHeadless()) {
|
||
|
Object key = getPrivateKey(target);
|
||
|
if (peerMap.get(key) == peer) {
|
||
|
peerMap.remove(key);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// mapping of Components to AppContexts, WeakHashMap<Component,AppContext>
|
||
|
private static final Map appContextMap =
|
||
|
Collections.synchronizedMap(new WeakHashMap());
|
||
|
|
||
|
/*
|
||
|
* Fetch the AppContext associated with the given target.
|
||
|
* This can be used to determine things like which EventQueue
|
||
|
* to use for posting events to a Component. If the target is
|
||
|
* null or the target can't be found, a null with be returned.
|
||
|
*/
|
||
|
public static AppContext targetToAppContext(Object target) {
|
||
|
if (target != null && !GraphicsEnvironment.isHeadless()) {
|
||
|
return (AppContext)appContextMap.get(getPrivateKey(target));
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the synchronous status of focus requests on lightweight
|
||
|
* components in the specified window to the specified value.
|
||
|
* If the boolean parameter is <code>true</code> then the focus
|
||
|
* requests on lightweight components will be performed
|
||
|
* synchronously, if it is <code>false</code>, then asynchronously.
|
||
|
* By default, all windows have their lightweight request status
|
||
|
* set to asynchronous.
|
||
|
* <p>
|
||
|
* The application can only set the status of lightweight focus
|
||
|
* requests to synchronous for any of its windows if it doesn't
|
||
|
* perform focus transfers between different heavyweight containers.
|
||
|
* In this case the observable focus behaviour is the same as with
|
||
|
* asynchronous status.
|
||
|
* <p>
|
||
|
* If the application performs focus transfer between different
|
||
|
* heavyweight containers and sets the lightweight focus request
|
||
|
* status to synchronous for any of its windows, then further focus
|
||
|
* behaviour is unspecified.
|
||
|
* <p>
|
||
|
* @param w window for which the lightweight focus request status
|
||
|
* should be set
|
||
|
* @param status the value of lightweight focus request status
|
||
|
*/
|
||
|
public static native void setLWRequestStatus(Window changed, boolean status);
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Moves the specified component to the specified order index in the
|
||
|
* specified container.
|
||
|
* <p>
|
||
|
* If the component already exists in this container or a child of
|
||
|
* this container, it is removed from that container before being
|
||
|
* added to this container.
|
||
|
* <p>
|
||
|
* The important difference of this method from
|
||
|
* <p>
|
||
|
* <blockquote>
|
||
|
* <code>java.awt.Container.add(Component comp, int index)</code>
|
||
|
* </blockquote>
|
||
|
* <p>
|
||
|
* is that this method doesn't call <code>removeNotify</code> on
|
||
|
* comp while removing it from its previous container. This way,
|
||
|
* if the component is lightweight and has focus, it will be moved
|
||
|
* to the new position and keep the focus when the method returns.
|
||
|
* <p>
|
||
|
* This method should not be used to move the component from one
|
||
|
* heavyweight container to another, and it should not be used for
|
||
|
* heavyweight components. If such an attempt is made, the result
|
||
|
* is unspecified.
|
||
|
* <p>
|
||
|
* It is recommended to call this method on EventDispatchThread.
|
||
|
* <p>
|
||
|
* @param cont the container to which the component should be added
|
||
|
* @param comp the component that should be added
|
||
|
* @param order the position in the container's list at which to
|
||
|
* insert the component, where <code>-1</code> means
|
||
|
* append to the end.
|
||
|
* @exception IllegalArgumentException if <code>index</code> is invalid
|
||
|
* @exception IllegalArgumentException if adding the container's parent
|
||
|
* to itself
|
||
|
* @exception IllegalArgumentException if adding a window to a container
|
||
|
*/
|
||
|
public static native void setZOrder(Container cont, Component comp, int order);
|
||
|
|
||
|
/*
|
||
|
* Insert a mapping from target to AppContext, for later retrieval
|
||
|
* via targetToAppContext() above.
|
||
|
*/
|
||
|
public static void insertTargetMapping(Object target, AppContext appContext) {
|
||
|
if (!GraphicsEnvironment.isHeadless()) {
|
||
|
appContextMap.put(getPrivateKey(target), appContext);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Post an AWTEvent to the Java EventQueue, using the PostEventQueue
|
||
|
* to avoid possibly calling client code (EventQueueSubclass.postEvent())
|
||
|
* on the toolkit (AWT-Windows/AWT-Motif) thread. This function should
|
||
|
* not be called under another lock since it locks the EventQueue.
|
||
|
* See bugids 4632918, 4526597.
|
||
|
*/
|
||
|
public static void postEvent(AppContext appContext, AWTEvent event) {
|
||
|
if (event == null) {
|
||
|
throw new NullPointerException();
|
||
|
}
|
||
|
PostEventQueue postEventQueue =
|
||
|
(PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
|
||
|
if(postEventQueue != null) {
|
||
|
postEventQueue.postEvent(event);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Flush any pending events which haven't been posted to the AWT
|
||
|
* EventQueue yet.
|
||
|
*/
|
||
|
public static void flushPendingEvents() {
|
||
|
AppContext appContext = AppContext.getAppContext();
|
||
|
PostEventQueue postEventQueue =
|
||
|
(PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
|
||
|
if(postEventQueue != null) {
|
||
|
postEventQueue.flush();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static boolean isPostEventQueueEmpty() {
|
||
|
AppContext appContext = AppContext.getAppContext();
|
||
|
PostEventQueue postEventQueue =
|
||
|
(PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
|
||
|
if (postEventQueue != null) {
|
||
|
return postEventQueue.noEvents();
|
||
|
} else {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Execute a chunk of code on the Java event handler thread for the
|
||
|
* given target. Does not wait for the execution to occur before
|
||
|
* returning to the caller.
|
||
|
*/
|
||
|
public static void executeOnEventHandlerThread(Object target,
|
||
|
Runnable runnable) {
|
||
|
executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Execute a chunk of code on the Java event handler thread for the
|
||
|
* given target. Does not wait for the execution to occur before
|
||
|
* returning to the caller.
|
||
|
*/
|
||
|
public static void executeOnEventHandlerThread(PeerEvent peerEvent) {
|
||
|
postEvent(targetToAppContext(peerEvent.getSource()), peerEvent);
|
||
|
}
|
||
|
|
||
|
public Dimension getScreenSize() {
|
||
|
return new Dimension(getScreenWidth(), getScreenHeight());
|
||
|
}
|
||
|
protected abstract int getScreenWidth();
|
||
|
protected abstract int getScreenHeight();
|
||
|
|
||
|
public static final FontMetrics[] lastMetrics = new FontMetrics[5];
|
||
|
|
||
|
public FontMetrics getFontMetrics(Font font) {
|
||
|
for (int i = 0; i < lastMetrics.length; i++) {
|
||
|
FontMetrics lm = lastMetrics[i];
|
||
|
if (lm == null) {
|
||
|
break;
|
||
|
}
|
||
|
if (lm.getFont() == font) {
|
||
|
return lm;
|
||
|
}
|
||
|
}
|
||
|
FontMetrics lm = new FontDesignMetrics(font);
|
||
|
System.arraycopy(lastMetrics, 0, lastMetrics, 1, lastMetrics.length-1);
|
||
|
lastMetrics[0] = lm;
|
||
|
return lm;
|
||
|
}
|
||
|
|
||
|
public String[] getFontList() {
|
||
|
String[] hardwiredFontList = {
|
||
|
"Dialog", "SansSerif", "Serif", "Monospaced", "DialogInput"
|
||
|
|
||
|
// -- Obsolete font names from 1.0.2. It was decided that
|
||
|
// -- getFontList should not return these old names:
|
||
|
// "Helvetica", "TimesRoman", "Courier", "ZapfDingbats"
|
||
|
};
|
||
|
return hardwiredFontList;
|
||
|
}
|
||
|
|
||
|
public PanelPeer createPanel(Panel target) {
|
||
|
return (PanelPeer)createComponent(target);
|
||
|
}
|
||
|
|
||
|
public CanvasPeer createCanvas(Canvas target) {
|
||
|
return (CanvasPeer)createComponent(target);
|
||
|
}
|
||
|
|
||
|
static SoftCache imgCache = new SoftCache();
|
||
|
|
||
|
static synchronized java.awt.Image getImageFromHash(Toolkit tk, URL url) {
|
||
|
SecurityManager sm = System.getSecurityManager();
|
||
|
if (sm != null) {
|
||
|
try {
|
||
|
java.security.Permission perm =
|
||
|
url.openConnection().getPermission();
|
||
|
if (perm != null) {
|
||
|
try {
|
||
|
sm.checkPermission(perm);
|
||
|
} catch (SecurityException se) {
|
||
|
// fallback to checkRead/checkConnect for pre 1.2
|
||
|
// security managers
|
||
|
if ((perm instanceof java.io.FilePermission) &&
|
||
|
perm.getActions().indexOf("read") != -1) {
|
||
|
sm.checkRead(perm.getName());
|
||
|
} else if ((perm instanceof
|
||
|
java.net.SocketPermission) &&
|
||
|
perm.getActions().indexOf("connect") != -1) {
|
||
|
sm.checkConnect(url.getHost(), url.getPort());
|
||
|
} else {
|
||
|
throw se;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} catch (java.io.IOException ioe) {
|
||
|
sm.checkConnect(url.getHost(), url.getPort());
|
||
|
}
|
||
|
}
|
||
|
java.awt.Image img = (java.awt.Image)imgCache.get(url);
|
||
|
if (img == null) {
|
||
|
img = tk.createImage(new URLImageSource(url));
|
||
|
imgCache.put(url, img);
|
||
|
}
|
||
|
return img;
|
||
|
}
|
||
|
|
||
|
static synchronized java.awt.Image getImageFromHash(Toolkit tk,
|
||
|
String filename) {
|
||
|
SecurityManager security = System.getSecurityManager();
|
||
|
if (security != null) {
|
||
|
security.checkRead(filename);
|
||
|
}
|
||
|
java.awt.Image img = (java.awt.Image)imgCache.get(filename);
|
||
|
if (img == null) {
|
||
|
img = tk.createImage(new FileImageSource(filename));
|
||
|
imgCache.put(filename, img);
|
||
|
}
|
||
|
return img;
|
||
|
}
|
||
|
|
||
|
public java.awt.Image getImage(String filename) {
|
||
|
return getImageFromHash(this, filename);
|
||
|
}
|
||
|
|
||
|
public java.awt.Image getImage(URL url) {
|
||
|
return getImageFromHash(this, url);
|
||
|
}
|
||
|
|
||
|
public java.awt.Image createImage(String filename) {
|
||
|
SecurityManager security = System.getSecurityManager();
|
||
|
if (security != null) {
|
||
|
security.checkRead(filename);
|
||
|
}
|
||
|
return createImage(new FileImageSource(filename));
|
||
|
}
|
||
|
|
||
|
public java.awt.Image createImage(URL url) {
|
||
|
SecurityManager sm = System.getSecurityManager();
|
||
|
if (sm != null) {
|
||
|
try {
|
||
|
java.security.Permission perm =
|
||
|
url.openConnection().getPermission();
|
||
|
if (perm != null) {
|
||
|
try {
|
||
|
sm.checkPermission(perm);
|
||
|
} catch (SecurityException se) {
|
||
|
// fallback to checkRead/checkConnect for pre 1.2
|
||
|
// security managers
|
||
|
if ((perm instanceof java.io.FilePermission) &&
|
||
|
perm.getActions().indexOf("read") != -1) {
|
||
|
sm.checkRead(perm.getName());
|
||
|
} else if ((perm instanceof
|
||
|
java.net.SocketPermission) &&
|
||
|
perm.getActions().indexOf("connect") != -1) {
|
||
|
sm.checkConnect(url.getHost(), url.getPort());
|
||
|
} else {
|
||
|
throw se;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} catch (java.io.IOException ioe) {
|
||
|
sm.checkConnect(url.getHost(), url.getPort());
|
||
|
}
|
||
|
}
|
||
|
return createImage(new URLImageSource(url));
|
||
|
}
|
||
|
|
||
|
public java.awt.Image createImage(byte[] data, int offset, int length) {
|
||
|
return createImage(new ByteArrayImageSource(data, offset, length));
|
||
|
}
|
||
|
|
||
|
protected EventQueue getSystemEventQueueImpl() {
|
||
|
return getSystemEventQueueImplPP();
|
||
|
}
|
||
|
|
||
|
// Package private implementation
|
||
|
static EventQueue getSystemEventQueueImplPP() {
|
||
|
AppContext appContext = AppContext.getAppContext();
|
||
|
EventQueue theEventQueue =
|
||
|
(EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
|
||
|
return theEventQueue;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Give native peers the ability to query the native container
|
||
|
* given a native component (eg the direct parent may be lightweight).
|
||
|
*/
|
||
|
public static Container getNativeContainer(Component c) {
|
||
|
return Toolkit.getNativeContainer(c);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a new input method window, with behavior as specified in
|
||
|
* {@link java.awt.im.spi.InputMethodContext#createInputMethodWindow}.
|
||
|
* If the inputContext is not null, the window should return it from its
|
||
|
* getInputContext() method. The window needs to implement
|
||
|
* sun.awt.im.InputMethodWindow.
|
||
|
* <p>
|
||
|
* SunToolkit subclasses can override this method to return better input
|
||
|
* method windows.
|
||
|
*/
|
||
|
public Window createInputMethodWindow(String title, InputContext context) {
|
||
|
return new sun.awt.im.SimpleInputMethodWindow(title, context);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns whether enableInputMethods should be set to true for peered
|
||
|
* TextComponent instances on this platform. False by default.
|
||
|
*/
|
||
|
public boolean enableInputMethodsForTextComponent() {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private static Locale startupLocale = null;
|
||
|
|
||
|
/**
|
||
|
* Returns the locale in which the runtime was started.
|
||
|
*/
|
||
|
public static Locale getStartupLocale() {
|
||
|
if (startupLocale == null) {
|
||
|
String language, region, country, variant;
|
||
|
language = (String) AccessController.doPrivileged(
|
||
|
new GetPropertyAction("user.language", "en"));
|
||
|
// for compatibility, check for old user.region property
|
||
|
region = (String) AccessController.doPrivileged(
|
||
|
new GetPropertyAction("user.region"));
|
||
|
if (region != null) {
|
||
|
// region can be of form country, country_variant, or _variant
|
||
|
int i = region.indexOf('_');
|
||
|
if (i >= 0) {
|
||
|
country = region.substring(0, i);
|
||
|
variant = region.substring(i + 1);
|
||
|
} else {
|
||
|
country = region;
|
||
|
variant = "";
|
||
|
}
|
||
|
} else {
|
||
|
country = (String) AccessController.doPrivileged(
|
||
|
new GetPropertyAction("user.country", ""));
|
||
|
variant = (String) AccessController.doPrivileged(
|
||
|
new GetPropertyAction("user.variant", ""));
|
||
|
}
|
||
|
startupLocale = new Locale(language, country, variant);
|
||
|
}
|
||
|
return startupLocale;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the default keyboard locale of the underlying operating system
|
||
|
*/
|
||
|
public Locale getDefaultKeyboardLocale() {
|
||
|
return getStartupLocale();
|
||
|
}
|
||
|
|
||
|
private static String dataTransfererClassName = null;
|
||
|
|
||
|
protected static void setDataTransfererClassName(String className) {
|
||
|
dataTransfererClassName = className;
|
||
|
}
|
||
|
|
||
|
public static String getDataTransfererClassName() {
|
||
|
if (dataTransfererClassName == null) {
|
||
|
Toolkit.getDefaultToolkit(); // transferer set during toolkit init
|
||
|
}
|
||
|
return dataTransfererClassName;
|
||
|
}
|
||
|
|
||
|
// Support for window closing event notifications
|
||
|
private transient WindowClosingListener windowClosingListener = null;
|
||
|
/**
|
||
|
* @see sun.awt.WindowClosingSupport#getWindowClosingListener
|
||
|
*/
|
||
|
public WindowClosingListener getWindowClosingListener() {
|
||
|
return windowClosingListener;
|
||
|
}
|
||
|
/**
|
||
|
* @see sun.awt.WindowClosingSupport#setWindowClosingListener
|
||
|
*/
|
||
|
public void setWindowClosingListener(WindowClosingListener wcl) {
|
||
|
windowClosingListener = wcl;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @see sun.awt.WindowClosingListener#windowClosingNotify
|
||
|
*/
|
||
|
public RuntimeException windowClosingNotify(WindowEvent event) {
|
||
|
if (windowClosingListener != null) {
|
||
|
return windowClosingListener.windowClosingNotify(event);
|
||
|
} else {
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* @see sun.awt.WindowClosingListener#windowClosingDelivered
|
||
|
*/
|
||
|
public RuntimeException windowClosingDelivered(WindowEvent event) {
|
||
|
if (windowClosingListener != null) {
|
||
|
return windowClosingListener.windowClosingDelivered(event);
|
||
|
} else {
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} // class SunToolkit
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* PostEventQueue is a Thread that runs in the same AppContext as the
|
||
|
* Java EventQueue. It is a queue of AWTEvents to be posted to the
|
||
|
* Java EventQueue. The toolkit Thread (AWT-Windows/AWT-Motif) posts
|
||
|
* events to this queue, which then calls EventQueue.postEvent().
|
||
|
*
|
||
|
* We do this because EventQueue.postEvent() may be overridden by client
|
||
|
* code, and we mustn't ever call client code from the toolkit thread.
|
||
|
*/
|
||
|
class PostEventQueue {
|
||
|
private EventQueueItem queueHead = null;
|
||
|
private EventQueueItem queueTail = null;
|
||
|
private final EventQueue eventQueue;
|
||
|
|
||
|
PostEventQueue(EventQueue eq) {
|
||
|
eventQueue = eq;
|
||
|
}
|
||
|
|
||
|
public boolean noEvents() {
|
||
|
return queueHead == null;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Continually post pending AWTEvents to the Java EventQueue.
|
||
|
*/
|
||
|
public void flush() {
|
||
|
if (queueHead != null) {
|
||
|
EventQueueItem tempQueue;
|
||
|
/*
|
||
|
* We have to execute the loop inside the synchronized block
|
||
|
* to ensure that the flush is completed before a new event
|
||
|
* can be posted to this queue.
|
||
|
*/
|
||
|
synchronized (this) {
|
||
|
tempQueue = queueHead;
|
||
|
queueHead = queueTail = null;
|
||
|
/*
|
||
|
* If this PostEventQueue is flushed in parallel on two
|
||
|
* different threads tempQueue will be null for one of them.
|
||
|
*/
|
||
|
while (tempQueue != null) {
|
||
|
eventQueue.postEvent(tempQueue.event);
|
||
|
tempQueue = tempQueue.next;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Enqueue an AWTEvent to be posted to the Java EventQueue.
|
||
|
*/
|
||
|
void postEvent(AWTEvent event) {
|
||
|
EventQueueItem item = new EventQueueItem(event);
|
||
|
|
||
|
synchronized (this) {
|
||
|
if (queueHead == null) {
|
||
|
queueHead = queueTail = item;
|
||
|
} else {
|
||
|
queueTail.next = item;
|
||
|
queueTail = item;
|
||
|
}
|
||
|
}
|
||
|
SunToolkit.wakeupEventQueue(eventQueue, event.getSource() == AWTAutoShutdown.getInstance());
|
||
|
}
|
||
|
} // class PostEventQueue
|
||
|
|
||
|
class EventQueueItem {
|
||
|
AWTEvent event;
|
||
|
EventQueueItem next;
|
||
|
|
||
|
EventQueueItem(AWTEvent evt) {
|
||
|
event = evt;
|
||
|
}
|
||
|
} // class EventQueueItem
|