/* * This software is Licensed under the Lesser GNU Public License, a * copy of which can be found at * http://opensource.org/licenses/lgpl-license.php */ package bmsi.fsp; import java.io.InputStream; import java.io.IOException; /** Recognize sequences of bytes as virtual keys. @author Stuart D. Gathman Copyright (C) 2000 Business Management Systems, Inc. */ public class Keyboard { private InputStream in; public static final int UNDEF = -1; public Keyboard(InputStream in) { this.in = in; } /** An incremental key recognizer node. When you think about the overhead of a byte[], this structure really doesn't take any more memory than an array of byte[] and int - and it doesn't need sorting. */ static class Key { Key nxt, brn; int vk; // the virtual key, -1 if not defined final byte ch; // the byte value of this node Key(int c) { ch = (byte)c; vk = UNDEF; } } /** The Key node for a zero length sequence. This also serves as the root of the tree. */ private final Key root = new Key(0); /** Remove all virtual key mappings. */ public void clear() { root.brn = null; } /** Map a sequence of bytes to a virtual key. The sequence of bytes may have zero length. This will assign a virtual key code returned when there is no keyboard input available. @param seq the sequence of bytes @param key the virtual key code, UNDEF if undefined */ public void defineKey(byte[] seq,int key) { Key cur = root; int lev = 0; while (lev < seq.length) { byte ch = seq[lev++]; if (cur.brn == null) cur.brn = new Key(ch); cur = cur.brn; while (cur.ch != ch) { if (cur.nxt == null) cur.nxt = new Key(ch); cur = cur.nxt; } } cur.vk = key; } /** Return the next virtual key from the InputStream. */ public int readKey() throws IOException { Key cur = root; int lev = 0; while (cur.brn != null) { int c = in.read(); if (c < 0) break; // EOF or timeout cur = cur.brn; ++lev; while (cur.ch != (byte)c) { cur = cur.nxt; if (cur == null) { if (lev == 1) return c; return UNDEF; // not recognized } } } return cur.vk; } }