4632N/A/*
5990N/A * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
4632N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4632N/A *
4632N/A * This code is free software; you can redistribute it and/or modify it
4632N/A * under the terms of the GNU General Public License version 2 only, as
4632N/A * published by the Free Software Foundation. Oracle designates this
4632N/A * particular file as subject to the "Classpath" exception as provided
4632N/A * by Oracle in the LICENSE file that accompanied this code.
4632N/A *
4632N/A * This code is distributed in the hope that it will be useful, but WITHOUT
4632N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4632N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4632N/A * version 2 for more details (a copy is included in the LICENSE file that
4632N/A * accompanied this code).
4632N/A *
4632N/A * You should have received a copy of the GNU General Public License version
4632N/A * 2 along with this work; if not, write to the Free Software Foundation,
4632N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4632N/A *
4632N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4632N/A * or visit www.oracle.com if you need additional information or have any
4632N/A * questions.
4632N/A */
4632N/A
4632N/Apackage sun.lwawt;
4632N/A
4632N/Aimport java.awt.*;
4632N/Aimport java.awt.List;
4632N/Aimport java.awt.datatransfer.*;
4632N/Aimport java.awt.dnd.*;
4632N/Aimport java.awt.dnd.peer.*;
4632N/Aimport java.awt.image.*;
4632N/Aimport java.awt.peer.*;
4632N/Aimport java.security.*;
4632N/Aimport java.util.*;
4632N/A
4632N/Aimport sun.awt.*;
4632N/Aimport sun.lwawt.macosx.*;
4632N/Aimport sun.print.*;
4632N/A
4632N/Apublic abstract class LWToolkit extends SunToolkit implements Runnable {
4632N/A
4632N/A private final static int STATE_NONE = 0;
4632N/A private final static int STATE_INIT = 1;
4632N/A private final static int STATE_MESSAGELOOP = 2;
4632N/A private final static int STATE_SHUTDOWN = 3;
4632N/A private final static int STATE_CLEANUP = 4;
4632N/A private final static int STATE_DONE = 5;
4632N/A
4632N/A private int runState = STATE_NONE;
4632N/A
4632N/A private Clipboard clipboard;
4632N/A private MouseInfoPeer mouseInfoPeer;
4632N/A
4632N/A public LWToolkit() {
4632N/A }
4632N/A
4632N/A /*
4632N/A * This method is called by subclasses to start this toolkit
4632N/A * by launching the message loop.
4632N/A *
4632N/A * This method waits for the toolkit to be completely initialized
4632N/A * and returns before the message pump is started.
4632N/A */
4632N/A protected final void init() {
4632N/A AWTAutoShutdown.notifyToolkitThreadBusy();
4632N/A
4632N/A ThreadGroup mainTG = AccessController.doPrivileged(
4632N/A new PrivilegedAction<ThreadGroup>() {
4632N/A public ThreadGroup run() {
4632N/A ThreadGroup currentTG = Thread.currentThread().getThreadGroup();
4632N/A ThreadGroup parentTG = currentTG.getParent();
4632N/A while (parentTG != null) {
4632N/A currentTG = parentTG;
4632N/A parentTG = currentTG.getParent();
4632N/A }
4632N/A return currentTG;
4632N/A }
4632N/A }
4632N/A );
4632N/A
4632N/A Runtime.getRuntime().addShutdownHook(
4632N/A new Thread(mainTG, new Runnable() {
4632N/A public void run() {
4632N/A shutdown();
4632N/A waitForRunState(STATE_CLEANUP);
4632N/A }
4632N/A })
4632N/A );
4632N/A
4632N/A Thread toolkitThread = new Thread(mainTG, this, "AWT-LW");
4632N/A toolkitThread.setDaemon(true);
4632N/A toolkitThread.setPriority(Thread.NORM_PRIORITY + 1);
4632N/A toolkitThread.start();
4632N/A
4632N/A waitForRunState(STATE_MESSAGELOOP);
4632N/A }
4632N/A
4632N/A /*
4632N/A * Implemented in subclasses to initialize platform-dependent
4632N/A * part of the toolkit (open X display connection, create
4632N/A * toolkit HWND, etc.)
4632N/A *
4632N/A * This method is called on the toolkit thread.
4632N/A */
4632N/A protected abstract void platformInit();
4632N/A
4632N/A /*
4632N/A * Sends a request to stop the message pump.
4632N/A */
4632N/A public void shutdown() {
4632N/A setRunState(STATE_SHUTDOWN);
4632N/A platformShutdown();
4632N/A }
4632N/A
4632N/A /*
4632N/A * Implemented in subclasses to release all the platform-
4632N/A * dependent resources. Called after the message loop is
4632N/A * terminated.
4632N/A *
4632N/A * Could be called (always called?) on a non-toolkit thread.
4632N/A */
4632N/A protected abstract void platformShutdown();
4632N/A
4632N/A /*
4632N/A * Implemented in subclasses to release all the platform
4632N/A * resources before the application is terminated.
4632N/A *
4632N/A * This method is called on the toolkit thread.
4632N/A */
4632N/A protected abstract void platformCleanup();
4632N/A
4632N/A private synchronized int getRunState() {
4632N/A return runState;
4632N/A }
4632N/A
4632N/A private synchronized void setRunState(int state) {
4632N/A runState = state;
4632N/A notifyAll();
4632N/A }
4632N/A
4632N/A public boolean isTerminating() {
4632N/A return getRunState() >= STATE_SHUTDOWN;
4632N/A }
4632N/A
4632N/A private void waitForRunState(int state) {
4632N/A while (getRunState() < state) {
4632N/A try {
4632N/A synchronized (this) {
4632N/A wait();
4632N/A }
4632N/A } catch (InterruptedException z) {
4632N/A // TODO: log
4632N/A break;
4632N/A }
4632N/A }
4632N/A }
4632N/A
4632N/A public void run() {
4632N/A setRunState(STATE_INIT);
4632N/A platformInit();
4632N/A AWTAutoShutdown.notifyToolkitThreadFree();
4632N/A setRunState(STATE_MESSAGELOOP);
4632N/A while (getRunState() < STATE_SHUTDOWN) {
4632N/A try {
4632N/A platformRunMessage();
4632N/A if (Thread.currentThread().isInterrupted()) {
4632N/A if (AppContext.getAppContext().isDisposed()) {
4632N/A break;
4632N/A }
4632N/A }
4632N/A } catch (ThreadDeath td) {
4632N/A //XXX: if there isn't native code on the stack, the VM just
4632N/A //kills the thread right away. Do we expect to catch it
4632N/A //nevertheless?
4632N/A break;
4632N/A } catch (Throwable t) {
4632N/A // TODO: log
4632N/A System.err.println("Exception on the toolkit thread");
4632N/A t.printStackTrace(System.err);
4632N/A }
4632N/A }
4632N/A //XXX: if that's a secondary loop, jump back to the STATE_MESSAGELOOP
4632N/A setRunState(STATE_CLEANUP);
4632N/A AWTAutoShutdown.notifyToolkitThreadFree();
4632N/A platformCleanup();
4632N/A setRunState(STATE_DONE);
4632N/A }
4632N/A
4632N/A /*
4632N/A * Process the next message(s) from the native event queue.
4632N/A *
4632N/A * Initially, all the LWToolkit implementations were supposed
4632N/A * to have the similar message loop sequence: check if any events
4632N/A * available, peek events, wait. However, the later analysis shown
4632N/A * that X11 and Windows implementations are really different, so
4632N/A * let the subclasses do whatever they require.
4632N/A */
4632N/A protected abstract void platformRunMessage();
4632N/A
4632N/A public static LWToolkit getLWToolkit() {
4632N/A return (LWToolkit)Toolkit.getDefaultToolkit();
4632N/A }
4632N/A
4632N/A // ---- TOPLEVEL PEERS ---- //
4632N/A
4632N/A /*
4632N/A * Note that LWWindowPeer implements WindowPeer, FramePeer
4632N/A * and DialogPeer interfaces.
4632N/A */
4632N/A private LWWindowPeer createDelegatedPeer(Window target, PlatformComponent platformComponent,
5555N/A PlatformWindow platformWindow, LWWindowPeer.PeerType peerType)
4632N/A {
5555N/A LWWindowPeer peer = new LWWindowPeer(target, platformComponent, platformWindow, peerType);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public WindowPeer createWindow(Window target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.SIMPLEWINDOW);
5555N/A return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.SIMPLEWINDOW);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public FramePeer createFrame(Frame target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.FRAME);
5555N/A return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.FRAME);
4632N/A }
4632N/A
4655N/A public LWWindowPeer createEmbeddedFrame(CEmbeddedFrame target) {
4655N/A PlatformComponent platformComponent = createPlatformComponent();
5555N/A PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.EMBEDDED_FRAME);
5555N/A return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.EMBEDDED_FRAME);
4655N/A }
4632N/A
5555N/A public LWWindowPeer createEmbeddedFrame(CViewEmbeddedFrame target) {
5555N/A PlatformComponent platformComponent = createPlatformComponent();
5555N/A PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.VIEW_EMBEDDED_FRAME);
5555N/A return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.VIEW_EMBEDDED_FRAME);
5555N/A }
5555N/A
5555N/A
4632N/A CPrinterDialogPeer createCPrinterDialog(CPrinterDialog target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.DIALOG);
4632N/A CPrinterDialogPeer peer = new CPrinterDialogPeer(target, platformComponent, platformWindow);
4632N/A targetCreatedPeer(target, peer);
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public DialogPeer createDialog(Dialog target) {
4632N/A if (target instanceof CPrinterDialog) {
4632N/A return createCPrinterDialog((CPrinterDialog)target);
4632N/A }
4632N/A
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.DIALOG);
5555N/A return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.DIALOG);
4632N/A }
4632N/A
4632N/A @Override
4632N/A public FileDialogPeer createFileDialog(FileDialog target) {
4632N/A FileDialogPeer peer = createFileDialogPeer(target);
4632N/A targetCreatedPeer(target, peer);
4632N/A return peer;
4632N/A }
4632N/A
4632N/A // ---- LIGHTWEIGHT COMPONENT PEERS ---- //
4632N/A
4632N/A @Override
4632N/A public ButtonPeer createButton(Button target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWButtonPeer peer = new LWButtonPeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public CheckboxPeer createCheckbox(Checkbox target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWCheckboxPeer peer = new LWCheckboxPeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) {
4632N/A throw new RuntimeException("not implemented");
4632N/A }
4632N/A
4632N/A @Override
4632N/A public ChoicePeer createChoice(Choice target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWChoicePeer peer = new LWChoicePeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public LabelPeer createLabel(Label target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWLabelPeer peer = new LWLabelPeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public CanvasPeer createCanvas(Canvas target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWCanvasPeer peer = new LWCanvasPeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public ListPeer createList(List target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWListPeer peer = new LWListPeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public MenuPeer createMenu(Menu target) {
4632N/A throw new RuntimeException("not implemented");
4632N/A }
4632N/A
4632N/A @Override
4632N/A public MenuBarPeer createMenuBar(MenuBar target) {
4632N/A throw new RuntimeException("not implemented");
4632N/A }
4632N/A
4632N/A @Override
4632N/A public MenuItemPeer createMenuItem(MenuItem target) {
4632N/A throw new RuntimeException("not implemented");
4632N/A }
4632N/A
4632N/A @Override
4632N/A public PanelPeer createPanel(Panel target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWPanelPeer peer = new LWPanelPeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public PopupMenuPeer createPopupMenu(PopupMenu target) {
4632N/A throw new RuntimeException("not implemented");
4632N/A }
4632N/A
4632N/A @Override
4632N/A public ScrollPanePeer createScrollPane(ScrollPane target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWScrollPanePeer peer = new LWScrollPanePeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public ScrollbarPeer createScrollbar(Scrollbar target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWScrollBarPeer peer = new LWScrollBarPeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public TextAreaPeer createTextArea(TextArea target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWTextAreaPeer peer = new LWTextAreaPeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public TextFieldPeer createTextField(TextField target) {
4632N/A PlatformComponent platformComponent = createPlatformComponent();
4632N/A LWTextFieldPeer peer = new LWTextFieldPeer(target, platformComponent);
4632N/A targetCreatedPeer(target, peer);
4632N/A peer.initialize();
4632N/A return peer;
4632N/A }
4632N/A
4632N/A // ---- NON-COMPONENT PEERS ---- //
4632N/A
4632N/A @Override
4632N/A public ColorModel getColorModel() throws HeadlessException {
4632N/A return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getColorModel();
4632N/A }
4632N/A
4632N/A @Override
4632N/A public boolean isDesktopSupported() {
4632N/A return true;
4632N/A }
4632N/A
4632N/A @Override
4632N/A protected DesktopPeer createDesktopPeer(Desktop target) {
4632N/A return new CDesktopPeer();
4632N/A }
4632N/A
4632N/A @Override
4632N/A public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) {
4632N/A DragSourceContextPeer dscp = CDragSourceContextPeer.createDragSourceContextPeer(dge);
4632N/A
4632N/A return dscp;
4632N/A }
4632N/A
4632N/A @Override
5336N/A public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
5336N/A return LWKeyboardFocusManagerPeer.getInstance();
4632N/A }
4632N/A
4632N/A @Override
4632N/A public synchronized MouseInfoPeer getMouseInfoPeer() {
4632N/A if (mouseInfoPeer == null) {
4632N/A mouseInfoPeer = createMouseInfoPeerImpl();
4632N/A }
4632N/A return mouseInfoPeer;
4632N/A }
4632N/A
4632N/A protected MouseInfoPeer createMouseInfoPeerImpl() {
4632N/A return new LWMouseInfoPeer();
4632N/A }
4632N/A
4632N/A public PrintJob getPrintJob(Frame frame, String doctitle, Properties props) {
4632N/A return getPrintJob(frame, doctitle, null, null);
4632N/A }
4632N/A
4632N/A public PrintJob getPrintJob(Frame frame, String doctitle, JobAttributes jobAttributes, PageAttributes pageAttributes) {
4632N/A if (GraphicsEnvironment.isHeadless()) {
4632N/A throw new IllegalArgumentException();
4632N/A }
4632N/A
4632N/A PrintJob2D printJob = new PrintJob2D(frame, doctitle, jobAttributes, pageAttributes);
4632N/A
4632N/A if (printJob.printDialog() == false) {
4632N/A printJob = null;
4632N/A }
4632N/A
4632N/A return printJob;
4632N/A }
4632N/A
4632N/A @Override
4632N/A public RobotPeer createRobot(Robot target, GraphicsDevice screen) {
4632N/A throw new RuntimeException("not implemented");
4632N/A }
4632N/A
4632N/A @Override
4632N/A public boolean isTraySupported() {
4632N/A throw new RuntimeException("not implemented");
4632N/A }
4632N/A
4632N/A @Override
4632N/A public SystemTrayPeer createSystemTray(SystemTray target) {
4632N/A throw new RuntimeException("not implemented");
4632N/A }
4632N/A
4632N/A @Override
4632N/A public TrayIconPeer createTrayIcon(TrayIcon target) {
4632N/A throw new RuntimeException("not implemented");
4632N/A }
4632N/A
4632N/A @Override
4632N/A public Clipboard getSystemClipboard() {
4632N/A SecurityManager security = System.getSecurityManager();
4632N/A if (security != null) {
4632N/A security.checkSystemClipboardAccess();
4632N/A }
4632N/A
4632N/A synchronized (this) {
4632N/A if (clipboard == null) {
4632N/A clipboard = createPlatformClipboard();
4632N/A }
4632N/A }
4632N/A return clipboard;
4632N/A }
4632N/A
6323N/A protected abstract SecurityWarningWindow createSecurityWarning(Window ownerWindow, LWWindowPeer ownerPeer);
6323N/A
4632N/A // ---- DELEGATES ---- //
4632N/A
4632N/A public abstract Clipboard createPlatformClipboard();
4632N/A
4632N/A /*
4632N/A * Creates a delegate for the given peer type (window, frame, dialog, etc.)
4632N/A */
4632N/A protected abstract PlatformWindow createPlatformWindow(LWWindowPeer.PeerType peerType);
4632N/A
4632N/A protected abstract PlatformComponent createPlatformComponent();
4632N/A
4632N/A protected abstract FileDialogPeer createFileDialogPeer(FileDialog target);
4632N/A
4632N/A // ---- UTILITY METHODS ---- //
4632N/A
4632N/A /*
4632N/A * Expose non-public targetToPeer() method.
4632N/A */
4632N/A public final static Object targetToPeer(Object target) {
4632N/A return SunToolkit.targetToPeer(target);
4632N/A }
4632N/A
4632N/A /*
4632N/A * Expose non-public targetDisposedPeer() method.
4632N/A */
4632N/A public final static void targetDisposedPeer(Object target, Object peer) {
4632N/A SunToolkit.targetDisposedPeer(target, peer);
4632N/A }
4632N/A
4632N/A /*
4632N/A * Returns the current cursor manager.
4632N/A */
4632N/A public abstract LWCursorManager getCursorManager();
4632N/A
4632N/A public static void postEvent(AWTEvent event) {
4632N/A postEvent(targetToAppContext(event.getSource()), event);
4632N/A }
4639N/A
4665N/A @Override
4665N/A public void grab(Window w) {
4665N/A if (w.getPeer() != null) {
4665N/A ((LWWindowPeer)w.getPeer()).grab();
4665N/A }
4665N/A }
4665N/A
4665N/A @Override
4665N/A public void ungrab(Window w) {
4665N/A if (w.getPeer() != null) {
5990N/A ((LWWindowPeer)w.getPeer()).ungrab(false);
4665N/A }
4665N/A }
4632N/A}