Package org.jnode.driver.input

Source Code of org.jnode.driver.input.AbstractInputDriver

/*
* $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.input;

import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.util.ArrayList;

import org.jnode.driver.Driver;
import org.jnode.system.event.SystemEvent;
import org.jnode.util.Queue;
import org.jnode.util.QueueProcessor;
import org.jnode.util.QueueProcessorThread;

public abstract class AbstractInputDriver<E extends SystemEvent> extends Driver {
    private final ArrayList<SystemListener> listeners = new ArrayList<SystemListener>();

    private QueueProcessorThread<E> eventQueueThread;
    private Queue<E> eventQueue = new Queue<E>();
    private InputDaemon daemon;

    protected final void startDispatcher(String id) {
        this.eventQueue = new Queue<E>();
        this.daemon = new InputDaemon(id + "-daemon");
        this.daemon.start();

        this.eventQueueThread = new QueueProcessorThread<E>(id + "-dispatcher",
            eventQueue, new SystemEventDispatcher());
        this.eventQueueThread.start();
    }

    protected final void stopDispatcher() {
        if (eventQueueThread != null) {
            eventQueueThread.stopProcessor();
        }
        this.eventQueueThread = null;

        InputDaemon daemon = this.daemon;
        this.daemon = null;
        if (daemon != null) {
            daemon.setRunningState(false);
            daemon.interrupt();
        }
    }

    class SystemEventDispatcher implements QueueProcessor<E> {

        /**
         * @see org.jnode.util.QueueProcessor#process(java.lang.Object)
         */
        public void process(E event) throws Exception {
            for (SystemListener l : listeners) {
                sendEvent(l, event);
                if (event.isConsumed()) {
                    break;
                }
            }
        }
    }

    protected abstract void sendEvent(SystemListener<E> l, E e);

    /**
     * Add a pointer listener
     *
     * @param l
     */
    public final synchronized void addListener(SystemListener<E> l) {
        listeners.add(l);
    }

    /**
     * Remove a pointer listener
     *
     * @param l
     */
    public final synchronized void removeListener(SystemListener<E> l) {
        listeners.remove(l);
    }

    /**
     * Claim to be the preferred listener.
     * The given listener must have been added by addKeyboardListener.
     * <b>This is not checked by a security manager</b>
     *
     * @param l
     */
    protected final synchronized void setPreferredListener(SystemListener<E> l) {
        if (listeners.remove(l)) {
            listeners.add(0, l);
        }
    }


    protected abstract E handleScancode(byte b);

    /**
     * Gets the byte channel. This is implementation specific
     *
     * @return The byte channel
     */
    protected abstract ByteChannel getChannel();

    /**
     * InputDaemon that translates scancodes to SystemEvents and dispatches those events.
     */
    class InputDaemon extends Thread {
        private boolean runningState;

        public InputDaemon(String name) {
            super(name);
        }

        public void run() {
            processChannel();
        }

        /**
         * Read scancodes from the input channel and dispatch them as events.
         */
        final void processChannel() {
            final ByteBuffer buf = ByteBuffer.allocate(1);
            final ByteChannel channel = getChannel();
            setRunningState(true);
            while ((channel != null) && channel.isOpen() && isRunningState()) {
                try {
                    buf.rewind();
                    if (channel.read(buf) != 1) {
                        continue;
                    }
                    final byte scancode = buf.get(0);
                    E event = handleScancode(scancode);
                    if ((event != null) && !event.isConsumed()) {
                        if (eventQueue.isClosed()) {
                            // the queue is closed : it usually happen while JNode is halting
                            // simply stop processing the events
                            break;
                        }
                       
                        eventQueue.add(event);
                    }
                } catch (Throwable ex) {
                    ex.printStackTrace();
                }
            }
        }

        public synchronized boolean isRunningState() {
            return runningState;
        }

        public synchronized void setRunningState(boolean runningState) {
            this.runningState = runningState;
        }
    }
}
TOP

Related Classes of org.jnode.driver.input.AbstractInputDriver

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.