Package org.jnode.driver.textscreen.swing

Source Code of org.jnode.driver.textscreen.swing.SwingPcTextScreen

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.driver.textscreen.swing;

import java.awt.AWTEvent;
import java.awt.AWTKeyStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

import org.jnode.driver.Bus;
import org.jnode.driver.Device;
import org.jnode.driver.Driver;
import org.jnode.driver.DriverException;
import org.jnode.driver.input.KeyboardAPI;
import org.jnode.driver.input.KeyboardEvent;
import org.jnode.driver.input.KeyboardInterpreter;
import org.jnode.driver.input.KeyboardListener;
import org.jnode.driver.input.PointerAPI;
import org.jnode.driver.input.PointerEvent;
import org.jnode.driver.input.PointerListener;
import org.jnode.driver.textscreen.TextScreen;
import org.jnode.driver.textscreen.x86.AbstractPcTextScreen;

/**
* A Swing based emulator for PcTextScreen.
*
* @author Levente S\u00e1ntha
*/
public class SwingPcTextScreen extends AbstractPcTextScreen {
    private static final int SCREEN_WIDTH = 80;
    private static final int SCREEN_HEIGHT = 25;
    char[] buffer;
    private int cursorOffset;
    private JComponent screen;
    private MyKeyboardDriver keyboardDriver = null;
    private Device keyboardDevice;
    private KeyAdapter keyListener;
    private MyPointerDriver pointerDriver = null;
    private Device pointerDevice;
    private MouseHandler mouseListener;

    public SwingPcTextScreen() {
        super(SCREEN_WIDTH, SCREEN_HEIGHT);
        buffer = new char[SCREEN_WIDTH * SCREEN_HEIGHT];
        for (int i = 0; i < buffer.length; i++) {
            buffer[i] = ' ';
        }

        screen = new SwingPcScreen();
    }

    public void close() {
        screen.removeKeyListener(keyListener);
        screen.removeMouseListener(mouseListener);
        screen.removeMouseMotionListener(mouseListener);
        screen.removeMouseWheelListener(mouseListener);
    }

    public JComponent getScreenComponent() {
        return screen;
    }

    private class SwingPcScreen extends JComponent {
        private static final long serialVersionUID = 1L;
        int margin = 5;
        int w;
        int h;

        {
            Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize();

            Font font = screen_size.width > 800 ?
                new Font("-dosemu-VGA-Medium-R-Normal--19-190-75-75-C-100-IBM-", Font.PLAIN, 18) :
                new Font("-Misc-Fixed-Medium-R-SemiCondensed--12-110-75-75-C-60-437-", Font.PLAIN, 12);

//            Font font = new Font("-Misc-Fixed-Medium-R-SemiCondensed--12-110-75-75-C-60-437-", Font.PLAIN, 12);
            //Font font = new Font(
            //"-FontForge-Bitstream Vera Sans Mono-Book-R-Normal-SansMono--12-120-75-75-P-69-ISO10646", Font.PLAIN, 12);
            //Font font = new Font("-FontForge-Bitstream Vera Sans
            // Mono-Book-R-Normal-SansMono--12-120-75-75-P-69-FontSpecific", Font.PLAIN, 12);
            //Font font = new Font("-FontForge-Bitstream Vera Sans
            // Mono-Book-R-Normal-SansMono--14-100-100-100-P-79-FontSpecific", Font.PLAIN, 12);
            // Font font = Font.decode("MONOSPACED-PLAIN-14");
            setFont(font);
            enableEvents(AWTEvent.KEY_EVENT_MASK);
            enableEvents(AWTEvent.FOCUS_EVENT_MASK);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    if (SwingUtilities.isLeftMouseButton(e)) {
                        if (contains(e.getX(), e.getY())) {
                            if (!hasFocus() && isRequestFocusEnabled()) {
                                requestFocus();
                            }
                        }
                    }
                }
            });
            setFocusable(true);
            setBackground(Color.BLACK);
            Set<AWTKeyStroke> ftk = new HashSet<AWTKeyStroke>(
                    getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
            ftk.remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
            setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, ftk);
        }

        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(getBackground());
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.WHITE);
            for (int i = 0; i < SCREEN_HEIGHT; i++) {
                int offset = i * SCREEN_WIDTH;
                int lenght = SCREEN_WIDTH;
                if (offset <= cursorOffset && cursorOffset < offset + SCREEN_WIDTH) {
                    FontMetrics fm = getFontMetrics(getFont());
                    int x = margin + fm.charsWidth(buffer, offset, cursorOffset - offset);
                    int y = h + i * h;
                    int width = fm.charWidth(buffer[cursorOffset]);
                    g.drawLine(x, y, x + width, y);
                }
                g.drawChars(buffer, offset, lenght, margin, h + i * h);

            }
        }

        @Override
        public void addNotify() {
            super.addNotify();
            FontMetrics fm = getGraphics().getFontMetrics();
            w = fm.getMaxAdvance();
            h = fm.getHeight();
            screen.setSize(screen.getMaximumSize());
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(w * SCREEN_WIDTH + 2 * margin, (h + 1) * SCREEN_HEIGHT + 2 * margin);
        }

        @Override
        public Dimension getMaximumSize() {
            return getPreferredSize();
        }
    }

    public Device getKeyboardDevice() {
        if (keyboardDevice == null) {
            keyboardDriver = new MyKeyboardDriver();
            keyListener = new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    KeyboardEvent k = new KeyboardEvent(KeyEvent.KEY_PRESSED,
                        e.getWhen(), e.getModifiersEx(), e.getKeyCode(), e.getKeyChar());
                    keyboardDriver.dispatchEvent(k);

                }

                @Override
                public void keyReleased(KeyEvent e) {
                    KeyboardEvent k = new KeyboardEvent(KeyEvent.KEY_RELEASED,
                        e.getWhen(), e.getModifiersEx(), e.getKeyCode(), e.getKeyChar());
                    keyboardDriver.dispatchEvent(k);
                }
            };
            screen.addKeyListener(keyListener);
            keyboardDevice = new Device(new Bus((Bus) null) {
            }, "");
            try {
                keyboardDevice.setDriver(keyboardDriver);
                keyboardDriver.startDevice();
            } catch (DriverException x) {
                throw new RuntimeException(x);
            }
        }
        return keyboardDevice;
    }

    private class MouseHandler extends MouseAdapter implements MouseMotionListener, MouseWheelListener {
        @Override
        public void mousePressed(MouseEvent e) {
            // todo complete event parameters
            PointerEvent p = new PointerEvent(0, e.getX(), e.getY(), true);
            pointerDriver.dispatchEvent(p);
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            // todo complete event parameters
            PointerEvent p = new PointerEvent(0, e.getX(), e.getY(), true);
            pointerDriver.dispatchEvent(p);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            // todo complete event parameters
            PointerEvent p = new PointerEvent(0, e.getX(), e.getY(), true);
            pointerDriver.dispatchEvent(p);
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            // todo complete event parameters
            PointerEvent p = new PointerEvent(0, e.getX(), e.getY(), true);
            pointerDriver.dispatchEvent(p);
        }

        @Override
        public void mouseWheelMoved(MouseWheelEvent e) {
            // todo complete event parameters
            PointerEvent p = new PointerEvent(0, e.getX(), e.getY(), e.getWheelRotation(), true);
            pointerDriver.dispatchEvent(p);
        }
    }

    public Device getPointerDevice() {
        if (pointerDevice == null) {
            pointerDriver = new MyPointerDriver();
            mouseListener = new MouseHandler();
            screen.addMouseListener(mouseListener);
            screen.addMouseMotionListener(mouseListener);
            screen.addMouseWheelListener(mouseListener);
            pointerDevice = new Device(new Bus((Bus) null) {
            }, "");
            try {
                pointerDevice.setDriver(pointerDriver);
                pointerDriver.startDevice();
            } catch (DriverException x) {
                throw new RuntimeException(x);
            }
        }
        return pointerDevice;
    }

    public char getChar(int offset) {
        return buffer[offset];
    }

    public int getColor(int offset) {
        return 0;
    }

    public void set(int offset, char ch, int count, int color) {
        char c = (char) (ch & 0xFF);
        c = ((c == 0) ? ' ' : c);
        for (int i = 0; i < count; i++) {
            buffer[offset] = c;
        }
        sync(offset, count);
    }

    public void set(int offset, char[] ch, int chOfs, int length, int color) {
        char[] cha = new char[ch.length];
        for (int i = 0; i < cha.length; i++) {
            char c = (char) (ch[i] & 0xFF);
            cha[i] = c == 0 ? ' ' : c;
        }
        System.arraycopy(cha, chOfs, buffer, offset, length);
        sync(offset, length);
    }

    public void set(int offset, char[] ch, int chOfs, int length, int[] colors, int colorsOfs) {
        char[] cha = new char[ch.length];
        for (int i = 0; i < cha.length; i++) {
            char c = (char) (ch[i] & 0xFF);
            cha[i] = c == 0 ? ' ' : c;
        }
        System.arraycopy(cha, chOfs, buffer, offset, length);
        sync(offset, length);
    }

    public void copyContent(int srcOffset, int destOffset, int length) {
        System.arraycopy(buffer, srcOffset * 2, buffer, destOffset * 2, length * 2);
        sync(destOffset * 2, length * 2);
    }

    public void copyTo(TextScreen dst, int offset, int length) {

    }

    Runnable repaintCmd = new Runnable() {
        public void run() {
            screen.repaint();
        }
    };

    @Override
    public void sync(int offset, int length) {
        SwingUtilities.invokeLater(repaintCmd);
    }

    public int setCursor(int x, int y) {
        cursorOffset = getOffset(x, y);
        return cursorOffset;
    }

    public int setCursorVisible(boolean visible) {
        return cursorOffset;
    }

    /**
     * Copy the content of the given rawData into this screen.
     *
     * @param rawData
     * @param rawDataOffset
     */
    public void copyFrom(char[] rawData, int rawDataOffset) {
        if (rawDataOffset < 0) {
            // Unsafe.die("Screen:rawDataOffset = " + rawDataOffset);
        }
        char[] cha = new char[rawData.length];
        for (int i = 0; i < cha.length; i++) {
            char c = (char) (rawData[i] & 0xFF);
            cha[i] = c == 0 ? ' ' : c;
        }
        System.arraycopy(cha, rawDataOffset, buffer, 0, getWidth() * getHeight());
        sync(0, getWidth() * getHeight());
    }

    private static class MyPointerDriver extends Driver implements PointerAPI {
        private final ArrayList<PointerListener> listeners = new ArrayList<PointerListener>();

        @Override
        protected synchronized void startDevice() throws DriverException {
            getDevice().registerAPI(PointerAPI.class, this);
        }

        @Override
        protected synchronized void stopDevice() throws DriverException {

        }

        void dispatchEvent(PointerEvent event) {
            for (PointerListener l : listeners) {
                l.pointerStateChanged(event);
                if (event.isConsumed()) {
                    break;
                }
            }
        }

        @Override
        public void addPointerListener(PointerListener l) {
            listeners.add(l);
        }

        @Override
        public void removePointerListener(PointerListener l) {
            listeners.remove(l);
        }

        /**
         * Claim to be the preferred listener.
         * The given listener must have been added by addPointerListener.
         * If there is a security manager, this method will call
         * <code>checkPermission(new DriverPermission("setPreferredListener"))</code>.
         *
         * @param listener the prefered pointer listener
         */
        @Override
        public void setPreferredListener(PointerListener listener) {

        }
    }

    private static class MyKeyboardDriver extends Driver implements KeyboardAPI {
        private final ArrayList<KeyboardListener> listeners = new ArrayList<KeyboardListener>();

        @Override
        protected synchronized void startDevice() throws DriverException {
            getDevice().registerAPI(KeyboardAPI.class, this);
        }

        @Override
        protected synchronized void stopDevice() throws DriverException {

        }

        void dispatchEvent(KeyboardEvent event) {
            for (KeyboardListener l : listeners) {
                sendEvent(l, event);
                if (event.isConsumed()) {
                    break;
                }
            }
        }

        protected void sendEvent(KeyboardListener l, KeyboardEvent event) {
            if (event.isKeyPressed()) {
                l.keyPressed(event);
            } else if (event.isKeyReleased()) {
                l.keyReleased(event);
            }
        }

        @Override
        public void addKeyboardListener(KeyboardListener l) {
            listeners.add(l);
        }

        @Override
        public KeyboardInterpreter getKbInterpreter() {
            return null;
        }

        @Override
        public void removeKeyboardListener(KeyboardListener l) {
            listeners.remove(l);
        }

        @Override
        public void setKbInterpreter(KeyboardInterpreter kbInterpreter) {

        }

        @Override
        public void setPreferredListener(KeyboardListener l) {

        }
    }
}
TOP

Related Classes of org.jnode.driver.textscreen.swing.SwingPcTextScreen

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.