/******************************************************************************* * CogTool Copyright Notice and Distribution Terms * CogTool 1.3, Copyright (c) 2005-2013 Carnegie Mellon University * This software is distributed under the terms of the FSF Lesser * Gnu Public License (see LGPL.txt). * * CogTool 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. * * CogTool 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 CogTool; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * CogTool makes use of several third-party components, with the * following notices: * * Eclipse SWT version 3.448 * Eclipse GEF Draw2D version 3.2.1 * * Unless otherwise indicated, all Content made available by the Eclipse * Foundation is provided to you under the terms and conditions of the Eclipse * Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this * Content and is also available at http://www.eclipse.org/legal/epl-v10.html. * * CLISP version 2.38 * * Copyright (c) Sam Steingold, Bruno Haible 2001-2006 * This software is distributed under the terms of the FSF Gnu Public License. * See COPYRIGHT file in clisp installation folder for more information. * * ACT-R 6.0 * * Copyright (c) 1998-2007 Dan Bothell, Mike Byrne, Christian Lebiere & * John R Anderson. * This software is distributed under the terms of the FSF Lesser * Gnu Public License (see LGPL.txt). * * Apache Jakarta Commons-Lang 2.1 * * This product contains software developed by the Apache Software Foundation * (http://www.apache.org/) * * jopt-simple version 1.0 * * Copyright (c) 2004-2013 Paul R. Holser, Jr. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Mozilla XULRunner 1.9.0.5 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/. * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The J2SE(TM) Java Runtime Environment version 5.0 * * Copyright 2009 Sun Microsystems, Inc., 4150 * Network Circle, Santa Clara, California 95054, U.S.A. All * rights reserved. U.S. * See the LICENSE file in the jre folder for more information. ******************************************************************************/ package edu.cmu.cs.hcii.cogtool.util; import java.util.HashMap; public class KeyboardUtil { /** * Character used to represent a press of the SHIFT key */ public static final char SHIFT_CHAR = '\uE000'; /** * Character used to represent a press of the CTRL key */ public static final char CTRL_CHAR = '\uE001'; /** * Character used to represent a press of the ALT key */ public static final char ALT_CHAR = '\uE002'; /** * Character used to represent a press of the COMMAND key */ public static final char COMMAND_CHAR = '\uE003'; /** * Character used to represent a press of the FUNCTION shift key */ public static final char FUNCTION_CHAR = '\uE004'; /** * Character used to represent a press of the ESCAPE key */ public static final char ESC_CHAR = '\uE005'; /** * Character used to represent a press of the BACKSPACE key */ public static final char BS_CHAR = '\uE006'; /** * Character used to represent a press of the ENTER key */ public static final char CR_CHAR = '\uE007'; /** * Character used to represent a press of the CAPSLOCK toggle key */ public static final char CAPSLOCK_CHAR = '\uE008'; /** * Character used to represent a press of the DELETE key */ public static final char DEL_CHAR = '\uE00A'; /** * Character used to represent a press of the TAB key */ public static final char TAB_CHAR = '\uE009'; /** * Character used to represent a press of the MENU key */ public static final char MENU_CHAR = '\uE00B'; /** * Character used to represent a press of the up-arrow key */ public static final char UP_ARROW_CHAR = '\uE00C'; /** * Character used to represent a press of the down-arrow key */ public static final char DOWN_ARROW_CHAR = '\uE00D'; /** * Character used to represent a press of the left-arrow key */ public static final char LEFT_ARROW_CHAR = '\uE00E'; /** * Character used to represent a press of the right-arrow key */ public static final char RIGHT_ARROW_CHAR = '\uE00F'; /* * Future for function keys */ public static final char F1 = '\uE201'; public static final char F2 = '\uE202'; public static final char F3 = '\uE203'; public static final char F4 = '\uE204'; public static final char F5 = '\uE205'; public static final char F6 = '\uE206'; public static final char F7 = '\uE207'; public static final char F8 = '\uE208'; public static final char F9 = '\uE209'; public static final char F10 = '\uE20A'; public static final char F11 = '\uE20B'; public static final char F12 = '\uE20C'; public static final char F13 = '\uE20D'; public static final char F14 = '\uE20E'; public static final char F15 = '\uE20F'; public static final char F16 = '\uE210'; /* * Future use for alternate side/hand decisions */ public static final char LEFT_SHIFT = '\uE100'; public static final char RIGHT_SHIFT = '\uE101'; public static final char LEFT_CTRL = '\uE102'; public static final char RIGHT_CTRL = '\uE103'; public static final char LEFT_ALT = '\uE104'; public static final char RIGHT_ALT = '\uE105'; public static final char LEFT_COMMAND = '\uE106'; public static final char RIGHT_COMMAND = '\uE107'; public static final char LEFT_FUNCTION = '\uE108'; public static final char RIGHT_FUNCTION = '\uE109'; // Finger used for various keys public static final int THUMB = 1; public static final int INDEX_FINGER = 2; public static final int MIDDLE_FINGER = 3; public static final int RING_FINGER = 4; public static final int LITTLE_FINGER = 5; protected static class KeyData { final boolean leftHand; final boolean homeRow; final int finger; final double distance; final double theta; final boolean isModifier; final boolean isCommand; final String klmEquivalent; KeyData(boolean left, boolean home, int fing, double d, double th, boolean mod, boolean com, String klm) { leftHand = left; homeRow = home; finger = fing; distance = d; theta = th; isModifier = mod; isCommand = com; klmEquivalent = klm; } } protected final static KeyData DEFAULT_KEY_DATA = new KeyData(false, true, INDEX_FINGER, 0, 0, false, false, null); protected final static char ASCII_END = '~'; protected final static KeyData[] asciiData = new KeyData[ASCII_END + 1]; protected final static HashMap<Character, KeyData> nonAsciiData = new HashMap<Character, KeyData>(); static { putData('a', true, true, LITTLE_FINGER, 0, 0); putData('b', true, false, INDEX_FINGER, 1.41, 2.36); putData('c', true, false, MIDDLE_FINGER, 1, 1.57); putData('d', true, true, MIDDLE_FINGER, 0, 0); putData('e', true, false, MIDDLE_FINGER, 1, -1.57); putData('f', true, true, INDEX_FINGER, 0, 0); putData('g', true, false, INDEX_FINGER, 1, 0); putData('h', false, false, INDEX_FINGER, 1, 3.14); putData('i', false, false, MIDDLE_FINGER, 1, -1.57); putData('j', false, true, INDEX_FINGER, 0, 0); putData('k', false, true, MIDDLE_FINGER, 0, 0); putData('l', false, true, RING_FINGER, 0, 0); putData('m', false, false, INDEX_FINGER, 1, 1.57); putData('n', false, false, INDEX_FINGER, 1.41, 2.36); putData('o', false, false, RING_FINGER, 1, -1.57); putData('p', false, false, LITTLE_FINGER, 1, -1.57); putData('q', true, false, LITTLE_FINGER, 1, -1.57); putData('r', true, false, INDEX_FINGER, 1, -1.57); putData('s', true, true, RING_FINGER, 0, 0); putData('t', true, false, INDEX_FINGER, 1.41, -2.36); putData('u', false, false, INDEX_FINGER, 1, -1.57); putData('v', true, false, INDEX_FINGER, 1, 1.57); putData('w', true, false, RING_FINGER, 1, -1.57); putData('x', true, false, RING_FINGER, 1, 1.57); putData('y', false, false, INDEX_FINGER, 1.41, -2.36); putData('z', true, false, LITTLE_FINGER, 1, 1.57); putData('1', true, false, LITTLE_FINGER, 2, -1.57); putData('2', true, false, RING_FINGER, 2, -1.57); putData('3', true, false, MIDDLE_FINGER, 2, -1.57); putData('4', true, false, INDEX_FINGER, 2, -1.57); putData('5', true, false, INDEX_FINGER, 2.24, -1.11); putData('6', false, false, INDEX_FINGER, 2.24, -1.11); putData('7', false, false, INDEX_FINGER, 2, -1.57); putData('7', false, false, MIDDLE_FINGER, 2, -1.57); putData('8', false, false, RING_FINGER, 2, -1.57); putData('9', false, false, LITTLE_FINGER, 2, -1.57); putData('0', false, false, LITTLE_FINGER, 2, -1.57); putData(' ', true, true, THUMB, 0, 0); putData('`', true, false, LITTLE_FINGER, 2.24, -2.03); putData('-', false, false, LITTLE_FINGER, 2.24, -1.11); putData('=', false, false, LITTLE_FINGER, 2.83, -0.78); putData('[', false, false, LITTLE_FINGER, 1.41, -0.78); putData(']', false, false, LITTLE_FINGER, 2.24, -0.46); putData('\\', false, false, LITTLE_FINGER, 3.16, -0.32); putData(';', false, false, LITTLE_FINGER, 0, 0); putData('\'', false, false, LITTLE_FINGER, 1, 0); putData(',', false, false, MIDDLE_FINGER, 1, 1.57); putData('.', false, false, RING_FINGER, 1, 1.57); putData('/', false, false, LITTLE_FINGER, 1, 1.57); putData('~', true, false, LITTLE_FINGER, 2.24, -2.03, (SHIFT_CHAR + "`")); putData('!', true, false, LITTLE_FINGER, 2, -1.57, (SHIFT_CHAR + "1")); putData('@', true, false, RING_FINGER, 2, -1.57, (SHIFT_CHAR + "2")); putData('#', true, false, MIDDLE_FINGER, 2, -1.57, (SHIFT_CHAR + "3")); putData('$', true, false, INDEX_FINGER, 2, -1.57, (SHIFT_CHAR + "4")); putData('%', true, false, INDEX_FINGER, 2.24, -1.11, (SHIFT_CHAR + "5")); putData('^', false, false, INDEX_FINGER, 2.24, -1.11, (SHIFT_CHAR + "6")); putData('&', false, false, INDEX_FINGER, 2, -1.57, (SHIFT_CHAR + "7")); putData('*', false, false, MIDDLE_FINGER, 2, -1.57, (SHIFT_CHAR + "8")); putData('(', false, false, RING_FINGER, 2, -1.57, (SHIFT_CHAR + "9")); putData(')', false, false, LITTLE_FINGER, 2, -1.57, (SHIFT_CHAR + "0")); putData('_', false, false, LITTLE_FINGER, 2.24, -1.11, (SHIFT_CHAR + "-")); putData('+', false, false, LITTLE_FINGER, 2.83, -0.78, (SHIFT_CHAR + "=")); putData('{', false, false, LITTLE_FINGER, 1.41, -0.78, (SHIFT_CHAR + "[")); putData('}', false, false, LITTLE_FINGER, 2.24, -0.46, (SHIFT_CHAR + "]")); putData('|', false, false, LITTLE_FINGER, 3.16, -0.32, (SHIFT_CHAR + "\\")); putData(':', true, false, LITTLE_FINGER, 0, 0, (SHIFT_CHAR + ";")); putData('\"', false, false, LITTLE_FINGER, 1, 0, (SHIFT_CHAR + "\'")); putData('<', false, false, MIDDLE_FINGER, 1, 1.57, (SHIFT_CHAR + ",")); putData('>', false, false, RING_FINGER, 1, 1.57, (SHIFT_CHAR + ".")); putData('?', false, false, LITTLE_FINGER, 1, 1.57, (SHIFT_CHAR + "/")); // TODO figure out the right r and theta values for these putData(SHIFT_CHAR, true, false, LITTLE_FINGER, 1, 1.57, null, true, false); putData(CTRL_CHAR, true, false, LITTLE_FINGER, 1, 1.57, null, true, false); putData(ALT_CHAR, true, false, LITTLE_FINGER, 1, 1.57, null, true, false); putData(COMMAND_CHAR, true, false, LITTLE_FINGER, 1, 1.57, null, true, false); putData(FUNCTION_CHAR, true, false, LITTLE_FINGER, 1, 1.57, null, true, false); putData(CR_CHAR, false, false, LITTLE_FINGER, 2, 0, null, false, true); putData(ESC_CHAR, true, true, LITTLE_FINGER, 1, -1.57, null, false, true); putData(BS_CHAR, false, false, LITTLE_FINGER, 3.87, -0.59, null, false, true); putData(DEL_CHAR, false, false, LITTLE_FINGER, 3.87, -0.59, null, false, true); putData(CAPSLOCK_CHAR, true, true, LITTLE_FINGER, 1, 3.14, null, false, true); putData(UP_ARROW_CHAR, false, false, LITTLE_FINGER, 1, 1.57, null, false, true); putData(DOWN_ARROW_CHAR, false, false, LITTLE_FINGER, 1, 1.57, null, false, true); putData(LEFT_ARROW_CHAR, false, false, LITTLE_FINGER, 1, 1.57, null, false, true); putData(RIGHT_ARROW_CHAR, false, false, LITTLE_FINGER, 1, 1.57, null, false, true); putData(MENU_CHAR, false, false, LITTLE_FINGER, 1, 1.57, null, false, false); putData(TAB_CHAR, true, false, LITTLE_FINGER, 1.41, -2.36, null, false, false); }; private KeyboardUtil() { // Don't instantiate } protected static KeyData getData(char c) { KeyData result = null; if (c <= ASCII_END) { result = asciiData[c]; } else { result = nonAsciiData.get(new Character(c)); } return ((result != null) ? result : DEFAULT_KEY_DATA); } protected static void putData(char c, boolean left, boolean home, int fing, double d, double th, String klm, boolean mod, boolean com) { if (klm == null) { klm = Character.toString(c); if (Character.isUpperCase(c)) { klm = SHIFT_CHAR + klm; } } KeyData data = new KeyData(left, home, fing, d, th, mod, com, klm); if (c <= ASCII_END) { asciiData[c] = data; } else { nonAsciiData.put(new Character(c), data); } } protected static void putData(char c, boolean left, boolean home, int fing, double d, double th, String klm) { putData(c, left, home, fing, d, th, klm, false, false); } protected static void putData(char c, boolean left, boolean home, int fing, double d, double th) { putData(c, left, home, fing, d, th, null); if (Character.isLetter(c)) { putData(Character.toUpperCase(c), left, home, fing, d, th, null); } } public static String convertToKLM(char c) { return getData(c).klmEquivalent; } /** * Checks a character to see whether it is typed by the right hand. * @return true if a character is typed by the right hand */ public static boolean needsRightHand(char ch) { return ! getData(ch).leftHand; } public static boolean needsLeftHand(char ch) { return getData(ch).leftHand; } public static boolean isModifierKey(char ch) { return getData(ch).isModifier; } public static boolean isCommandKey(char ch) { return getData(ch).isCommand; } public static int fingerUsed(char ch) { return getData(ch).finger; } public static boolean onHomeRow(char ch) { return getData(ch).homeRow; } public static double distance(char ch) { return getData(ch).distance; } public static double theta(char ch) { return getData(ch).theta; } }