package it.cavallium.warppi.device.input; import it.cavallium.warppi.WarpPI; import it.cavallium.warppi.Platform.ConsoleUtils; import it.cavallium.warppi.StaticVars; import it.cavallium.warppi.device.chip.ParallelToSerial; import it.cavallium.warppi.device.chip.SerialToParallel; import it.cavallium.warppi.event.Key; import it.cavallium.warppi.event.KeyPressedEvent; import it.cavallium.warppi.event.KeyReleasedEvent; import it.cavallium.warppi.event.KeyboardEventListener; import it.cavallium.warppi.extra.mario.MarioScreen; import it.cavallium.warppi.extra.tetris.TetrisScreen; import it.cavallium.warppi.gui.GUIErrorMessage; import it.cavallium.warppi.gui.screens.KeyboardDebugScreen; import it.cavallium.warppi.gui.screens.Screen; public class Keyboard { public static volatile boolean alpha = false; public static volatile boolean shift = false; //From Serial private static final int RCK_pin = 35; private static final int SCK_and_CLK_pin = 38; private static final int SER_pin = 36; //To Serial private static final int SH_LD_pin = 37; private static final int QH_pin = 40; private static final int CLK_INH_pin = 33; private static volatile boolean[][] precedentStates = new boolean[8][8]; public static volatile boolean[][] debugKeysDown = new boolean[8][8]; public static volatile int debugKeyCode = -1; public static volatile int debugKeyCodeRelease = -1; private static volatile boolean refreshRequest = false; private static KeyboardEventListener additionalListener; public synchronized void startKeyboard() { final Thread kt = new Thread(() -> { if (WarpPI.getPlatform().isRunningOnRaspberry() == false) { try { while (true) { if (Keyboard.debugKeyCode != -1) { Keyboard.debugKey(Keyboard.debugKeyCode, false); Keyboard.debugKeyCode = -1; } if (Keyboard.debugKeyCodeRelease != -1) { Keyboard.debugKey(Keyboard.debugKeyCodeRelease, true); Keyboard.debugKeyCodeRelease = -1; } Thread.sleep(50); } } catch (final InterruptedException e) {} } else { WarpPI.getPlatform().getGpio().pinMode(Keyboard.CLK_INH_pin, WarpPI.getPlatform().getGpio().valueOutput()); WarpPI.getPlatform().getGpio().pinMode(Keyboard.RCK_pin, WarpPI.getPlatform().getGpio().valueOutput()); WarpPI.getPlatform().getGpio().pinMode(Keyboard.SER_pin, WarpPI.getPlatform().getGpio().valueOutput()); WarpPI.getPlatform().getGpio().pinMode(Keyboard.SH_LD_pin, WarpPI.getPlatform().getGpio().valueOutput()); WarpPI.getPlatform().getGpio().pinMode(Keyboard.SCK_and_CLK_pin, WarpPI.getPlatform().getGpio().valueOutput()); WarpPI.getPlatform().getGpio().pinMode(Keyboard.QH_pin, WarpPI.getPlatform().getGpio().valueInput()); WarpPI.getPlatform().getGpio().digitalWrite(Keyboard.CLK_INH_pin, false); WarpPI.getPlatform().getGpio().digitalWrite(Keyboard.RCK_pin, false); WarpPI.getPlatform().getGpio().digitalWrite(Keyboard.SER_pin, false); WarpPI.getPlatform().getGpio().digitalWrite(Keyboard.SH_LD_pin, false); WarpPI.getPlatform().getGpio().digitalWrite(Keyboard.SCK_and_CLK_pin, false); WarpPI.getPlatform().getGpio().digitalWrite(Keyboard.QH_pin, false); final SerialToParallel chip1 = new SerialToParallel(Keyboard.RCK_pin, Keyboard.SCK_and_CLK_pin /*SCK*/, Keyboard.SER_pin); final ParallelToSerial chip2 = new ParallelToSerial(Keyboard.SH_LD_pin, Keyboard.CLK_INH_pin, Keyboard.QH_pin, Keyboard.SCK_and_CLK_pin/*CLK*/); KeyboardDebugScreen.log("Started keyboard system"); while (true) { boolean[] data; for (int col = 0; col < 8; col++) { data = new boolean[8]; data[col] = true; chip1.write(data); data = chip2.read(); // KeyboardDebugScreen.ks[col] = data; for (int row = 0; row < 8; row++) { if (data[row] == true && Keyboard.precedentStates[row][col] == false) { // System.out.println("Pressed button at " + (row + 1) + ", " + (col + 1)); // KeyboardDebugScreen.log("Pressed button at " + (row + 1) + ", " + (col + 1)); Keyboard.keyRaw(row, col, false); } else if (data[row] == false && Keyboard.precedentStates[row][col] == true) { Keyboard.keyRaw(row, col, true); } // KeyboardDebugScreen.log("Released button at " + (row + 1) + ", " + (col + 1)); Keyboard.precedentStates[row][col] = data[row]; } } } } }); WarpPI.getPlatform().setThreadName(kt, "Keyboard thread"); kt.setPriority(Thread.NORM_PRIORITY + 1); WarpPI.getPlatform().setThreadDaemon(kt); kt.start(); } /** * * @param k * @param released true: released, false: pressed */ private static void debugKey(Key k, boolean released) { if (released) { Keyboard.keyReleased(k); } else { Keyboard.keyPressed(k); } } /** * * @param keyCode * @param released true: released, false: pressed */ public static void debugKey(final int keyCode, boolean released) { switch (keyCode) { case KeyboardAWTValues.VK_ESCAPE: debugKey(Key.BACK, released); break; case KeyboardAWTValues.VK_S: if (Keyboard.shift) { debugKey(Key.ARCSINE, released); } else if (Keyboard.alpha) { debugKey(Key.LETTER_S, released); } else { debugKey(Key.SINE, released); } break; case KeyboardAWTValues.VK_C: if (Keyboard.shift) { debugKey(Key.ARCCOSINE, released); } else if (Keyboard.alpha) { debugKey(Key.LETTER_C, released); } else { debugKey(Key.COSINE, released); } break; case KeyboardAWTValues.VK_T: if (Keyboard.shift) { debugKey(Key.ARCTANGENT, released); } else if (Keyboard.alpha) { debugKey(Key.LETTER_T, released); } else { debugKey(Key.TANGENT, released); } break; case KeyboardAWTValues.VK_D: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.debug_DEG, released); } else if (Keyboard.alpha) { debugKey(Key.LETTER_D, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_R: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.debug_RAD, released); } else if (Keyboard.alpha) { debugKey(Key.LETTER_R, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_G: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.debug_GRA, released); } else if (Keyboard.alpha) { debugKey(Key.LETTER_G, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_X: if (Keyboard.alpha) { debugKey(Key.LETTER_X, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_P: if (Keyboard.shift) { debugKey(Key.NONE, released); } else if (Keyboard.alpha) { debugKey(Key.LETTER_P, released); } else { debugKey(Key.PI, released); } break; case KeyboardAWTValues.VK_E: if (Keyboard.shift) { debugKey(Key.NONE, released); } else if (Keyboard.alpha) { debugKey(Key.LETTER_E, released); } else { debugKey(Key.EULER_NUMBER, released); } break; case KeyboardAWTValues.VK_Y: if (Keyboard.alpha) { debugKey(Key.LETTER_Y, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_B: if (Keyboard.shift) { debugKey(Key.BRIGHTNESS_CYCLE_REVERSE, released); } else if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.BRIGHTNESS_CYCLE, released); } else { debugKey(Key.LETTER_B, released); } break; case KeyboardAWTValues.VK_L: if (Keyboard.shift) { debugKey(Key.LOGARITHM, released); } else if (Keyboard.alpha) { debugKey(Key.LETTER_L, released); } else { debugKey(Key.LOGARITHM, released); } break; case KeyboardJogampValues.VK_ENTER: case KeyboardAWTValues.VK_ENTER: if (Keyboard.shift) { debugKey(Key.STEP, released); } else if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.SIMPLIFY, released); } else { debugKey(Key.NONE, released); } int row = 2; int col = 1; Keyboard.debugKeysDown[row - 1][col - 1] = true; break; case KeyboardAWTValues.VK_1: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NUM1, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_2: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NUM2, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_3: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NUM3, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_4: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NUM4, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_5: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NUM5, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_6: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NUM6, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_7: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NUM7, released); } else if (Keyboard.shift) { if (WarpPI.getPlatform().isRunningOnRaspberry() == false) { debugKey(Key.DIVIDE, released); } } break; case KeyboardAWTValues.VK_8: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NUM8, released); } else if (Keyboard.shift) { debugKey(Key.PARENTHESIS_OPEN, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_9: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NUM9, released); } else if (Keyboard.shift) { debugKey(Key.PARENTHESIS_CLOSE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_0: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NUM0, released); } else if (Keyboard.shift) { debugKey(Key.EQUAL, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_M: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.SURD_MODE, released); } else if (Keyboard.shift) { debugKey(Key.NONE, released); } else { debugKey(Key.LETTER_M, released); } break; case KeyboardJogampValues.VK_ADD: case KeyboardAWTValues.VK_ADD: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.PLUS, released); } else if (Keyboard.shift) { debugKey(Key.PLUS_MINUS, released); } else { debugKey(Key.NONE, released); } break; case KeyboardJogampValues.VK_SUBTRACT: case KeyboardAWTValues.VK_SUBTRACT: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.MINUS, released); } else { debugKey(Key.NONE, released); } break; case KeyboardJogampValues.VK_MULTIPLY: case KeyboardAWTValues.VK_MULTIPLY: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.MULTIPLY, released); } else { debugKey(Key.NONE, released); } break; case KeyboardJogampValues.VK_DIVIDE: case KeyboardAWTValues.VK_DIVIDE: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.DIVIDE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_BACK_SPACE: debugKey(Key.DELETE, released); break; case KeyboardJogampValues.VK_DELETE: case KeyboardAWTValues.VK_DELETE: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.RESET, released); } else { debugKey(Key.NONE, released); } break; case KeyboardJogampValues.VK_LEFT: case KeyboardAWTValues.VK_LEFT: //LEFT row = 2; col = 3; Keyboard.debugKeysDown[row - 1][col - 1] = true; if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.LEFT, released); } else { debugKey(Key.NONE, released); } break; case KeyboardJogampValues.VK_RIGHT: case KeyboardAWTValues.VK_RIGHT: //RIGHT row = 2; col = 5; Keyboard.debugKeysDown[row - 1][col - 1] = true; if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.RIGHT, released); } else { debugKey(Key.NONE, released); } break; case KeyboardJogampValues.VK_UP: case KeyboardAWTValues.VK_UP: //UP row = 1; col = 4; Keyboard.debugKeysDown[row - 1][col - 1] = true; if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.UP, released); } else { debugKey(Key.NONE, released); } break; case KeyboardJogampValues.VK_DOWN: case KeyboardAWTValues.VK_DOWN: //DOWN row = 3; col = 4; Keyboard.debugKeysDown[row - 1][col - 1] = true; if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.DOWN, released); } else { debugKey(Key.NONE, released); } break; case (short) 12: //DOWN row = 2; col = 4; Keyboard.debugKeysDown[row - 1][col - 1] = true; if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.OK, released); } else { debugKey(Key.NONE, released); } break; case KeyboardJogampValues.VK_NUMPAD4: case KeyboardAWTValues.VK_NUMPAD4: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.HISTORY_BACK, released); } else { debugKey(Key.NONE, released); } break; case KeyboardJogampValues.VK_NUMPAD6: case KeyboardAWTValues.VK_NUMPAD6: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.HISTORY_FORWARD, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_PERIOD: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.DOT, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_A: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_A, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_F: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_F, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_H: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_H, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_I: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_I, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_J: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_J, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_K: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_K, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_N: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_N, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_O: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_O, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_Q: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_Q, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_U: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_U, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_V: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_V, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_W: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_W, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardAWTValues.VK_Z: if (!Keyboard.shift && !Keyboard.alpha) { debugKey(Key.NONE, released); } else if (Keyboard.alpha && !Keyboard.shift) { debugKey(Key.LETTER_Z, released); } else if (Keyboard.shift && !Keyboard.alpha) { debugKey(Key.ZOOM_MODE, released); } else { debugKey(Key.NONE, released); } break; case KeyboardJogampValues.VK_SHIFT: case KeyboardAWTValues.VK_SHIFT: debugKey(Key.SHIFT, released); break; case KeyboardAWTValues.VK_CONTROL: debugKey(Key.ALPHA, released); break; case KeyboardJogampValues.VK_NUMPAD1: case KeyboardAWTValues.VK_NUMPAD1: debugKey(Key.SQRT, released); break; case KeyboardJogampValues.VK_NUMPAD2: case KeyboardAWTValues.VK_NUMPAD2: debugKey(Key.ROOT, released); break; case KeyboardJogampValues.VK_NUMPAD3: case KeyboardAWTValues.VK_NUMPAD3: debugKey(Key.POWER_OF_2, released); break; case KeyboardJogampValues.VK_NUMPAD5: case KeyboardAWTValues.VK_NUMPAD5: debugKey(Key.POWER_OF_x, released); break; } } private synchronized static void debugKeyReleased(final int keyCode) { switch (keyCode) { case KeyboardAWTValues.VK_ENTER: int row = 2; int col = 1; Keyboard.debugKeysDown[row - 1][col - 1] = false; break; case KeyboardJogampValues.VK_LEFT: case KeyboardAWTValues.VK_LEFT: //LEFT row = 2; col = 3; Keyboard.debugKeysDown[row - 1][col - 1] = false; break; case KeyboardJogampValues.VK_RIGHT: case KeyboardAWTValues.VK_RIGHT: //RIGHT row = 2; col = 5; Keyboard.debugKeysDown[row - 1][col - 1] = false; System.out.println("RELEASE"); break; case KeyboardJogampValues.VK_UP: case KeyboardAWTValues.VK_UP: //UP row = 1; col = 4; Keyboard.debugKeysDown[row - 1][col - 1] = false; break; case KeyboardJogampValues.VK_DOWN: case KeyboardAWTValues.VK_DOWN: //DOWN row = 3; col = 4; Keyboard.debugKeysDown[row - 1][col - 1] = false; break; case (short) 12: //DOWN row = 2; col = 4; Keyboard.debugKeysDown[row - 1][col - 1] = false; break; } } /** * * @param row * @param col * @return */ @Deprecated public static boolean isKeyDown(final int row, final int col) { if (WarpPI.getPlatform().isRunningOnRaspberry()) { return Keyboard.precedentStates[row - 1][col - 1]; } else { return Keyboard.debugKeysDown[row - 1][col - 1]; } } static final String[][][] KeyLabelsMap = /* [ROW, COLUMN, (0:normal 1:shift 2:alpha)] */ { { /* ROW 0 */ { "⇪", "⇪", null }, /* 0,0 */ { "A", null, "A" }, /* 0,1 */ { "", null, null }, /* 0,2 */ { "⇧", null, null }, /* 0,3 */ { "", null, null }, /* 0,4 */ { "", null, null }, /* 0,5 */ { "☼", "☼", null }, /* 0,6 */ { "↩", null, null } /* 0,7 */ }, { /* ROW 1 */ { "", null, null }, /* 1,0 */ { "", null, null }, /* 1,1 */ { "⇦", null, null }, /* 1,2 */ { "OK", null, null }, /* 1,3 */ { "⇨", null, null }, /* 1,4 */ { "≪", null, null }, /* 1,5 */ { "≫", null, null }, /* 1,6 */ { "", null, null } /* 1,7 */ }, { /* ROW 2 */ { "", null, null }, /* 2,0 */ { "√▯", null, null }, /* 2,1 */ { "", null, null }, /* 2,2 */ { "⇩", null, null }, /* 2,3 */ { "↶", null, null }, /* 2,4 */ { "", null, null }, /* 2,5 */ { "", null, null }, /* 2,6 */ { "", null, null } /* 2,7 */ }, { /* ROW 3 */ { "", null, null }, /* 3,0 */ { "", null, null }, /* 3,1 */ { "▯^▯", null, null }, /* 3,2 */ { "▯^2", null, null }, /* 3,3 */ { "", null, null }, /* 3,4 */ { "", null, null }, /* 3,5 */ { "", null, null }, /* 3,6 */ { ".", null, "y" } /* 3,7 */ }, { /* ROW 4 */ { "", null, null }, /* 4,0 */ { "", null, null }, /* 4,1 */ { "(▯)", null, null }, /* 4,2 */ { ")", null, null }, /* 4,3 */ { "", null, null }, /* 4,4 */ { "S⇔D", null, null }, /* 4,5 */ { "", null, null }, /* 4,6 */ { "0", null, "x" } /* 4,7 */ }, { /* ROW 5 */ { "7", null, null }, /* 5,0 */ { "8", null, null }, /* 5,1 */ { "9", null, null }, /* 5,2 */ { "⌫", null, null }, /* 5,3 */ { "RESET", null, null }, /* 5,4 */ { "", null, null }, /* 5,5 */ { "", null, null }, /* 5,6 */ { "", null, null } /* 5,7 */ }, { /* ROW 6 */ { "4", null, null }, /* 6,0 */ { "5", null, null }, /* 6,1 */ { "6", null, null }, /* 6,2 */ { "*", null, null }, /* 6,3 */ { "/", null, null }, /* 6,4 */ { "", null, null }, /* 6,5 */ { "", null, null }, /* 6,6 */ { "", null, null } /* 6,7 */ }, { /* ROW 7 */ { "1", null, null }, /* 7,0 */ { "2", null, null }, /* 7,1 */ { "3", null, null }, /* 7,2 */ { "+", null, null }, /* 7,3 */ { "-", null, null }, /* 7,4 */ { "", null, null }, /* 7,5 */ { "", null, null }, /* 7,6 */ { "", null, null } /* 7,7 */ } }; static final Key[][][] keyMap = /* [ROW, COLUMN, (0:normal 1:shift 2:alpha)] */ { { /* ROW 0 */ { Key.SHIFT, Key.SHIFT, Key.SHIFT }, /* 0,0 */ { Key.ALPHA, Key.ALPHA, Key.ALPHA }, /* 0,1 */ { Key.NONE, Key.NONE, Key.NONE }, /* 0,2 */ { Key.UP, Key.NONE, Key.NONE }, /* 0,3 */ { Key.NONE, Key.NONE, Key.NONE }, /* 0,4 */ { Key.SETTINGS, Key.NONE, Key.NONE }, /* 0,5 */ { Key.BRIGHTNESS_CYCLE, Key.BRIGHTNESS_CYCLE_REVERSE, Key.ZOOM_MODE }, /* 0,6 */ { Key.SIMPLIFY, Key.STEP, Key.NONE } /* 0,7 */ }, { /* ROW 1 */ { Key.F4, Key.F4, Key.F4 }, /* 1,0 */ { Key.NONE, Key.NONE, Key.NONE }, /* 1,1 */ { Key.LEFT, Key.NONE, Key.NONE }, /* 1,2 */ { Key.OK, Key.NONE, Key.NONE }, /* 1,3 */ { Key.RIGHT, Key.NONE, Key.NONE }, /* 1,4 */ { Key.HISTORY_BACK, Key.NONE, Key.NONE }, /* 1,5 */ { Key.HISTORY_FORWARD, Key.NONE, Key.NONE }, /* 1,6 */ { Key.NONE, Key.PI, Key.DRG_CYCLE } /* 1,7 */ }, { /* ROW 2 */ { Key.F3, Key.F3, Key.F3 }, /* 2,0 */ { Key.SQRT, Key.ROOT, Key.NONE }, /* 2,1 */ { Key.NONE, Key.NONE, Key.NONE }, /* 2,2 */ { Key.DOWN, Key.NONE, Key.NONE }, /* 2,3 */ { Key.BACK, Key.NONE, Key.NONE }, /* 2,4 */ { Key.NONE, Key.NONE, Key.NONE }, /* 2,5 */ { Key.NONE, Key.NONE, Key.NONE }, /* 2,6 */ { Key.NONE, Key.NONE, Key.LETTER_Z } /* 2,7 */ }, { /* ROW 3 */ { Key.F2, Key.F2, Key.F2 }, /* 3,0 */ { Key.NONE, Key.NONE, Key.NONE }, /* 3,1 */ { Key.POWER_OF_x, Key.NONE, Key.NONE }, /* 3,2 */ { Key.POWER_OF_2, Key.NONE, Key.NONE }, /* 3,3 */ { Key.NONE, Key.NONE, Key.NONE }, /* 3,4 */ { Key.NONE, Key.NONE, Key.NONE }, /* 3,5 */ { Key.NONE, Key.NONE, Key.NONE }, /* 3,6 */ { Key.DOT, Key.NONE, Key.LETTER_Y } /* 3,7 */ }, { /* ROW 4 */ { Key.F1, Key.F1, Key.F1 }, /* 4,0 */ { Key.NONE, Key.NONE, Key.NONE }, /* 4,1 */ { Key.PARENTHESIS_OPEN, Key.NONE, Key.NONE }, /* 4,2 */ { Key.PARENTHESIS_CLOSE, Key.NONE, Key.NONE }, /* 4,3 */ { Key.NONE, Key.NONE, Key.NONE }, /* 4,4 */ { Key.SURD_MODE, Key.NONE, Key.NONE }, /* 4,5 */ { Key.NONE, Key.NONE, Key.NONE }, /* 4,6 */ { Key.NUM0, Key.NONE, Key.LETTER_X } /* 4,7 */ }, { /* ROW 5 */ { Key.NUM7, Key.NONE, Key.NONE }, /* 5,0 */ { Key.NUM8, Key.NONE, Key.NONE }, /* 5,1 */ { Key.NUM9, Key.NONE, Key.NONE }, /* 5,2 */ { Key.DELETE, Key.NONE, Key.NONE }, /* 5,3 */ { Key.RESET, Key.NONE, Key.NONE }, /* 5,4 */ { Key.NONE, Key.NONE, Key.NONE }, /* 5,5 */ { Key.NONE, Key.NONE, Key.NONE }, /* 5,6 */ { Key.NONE, Key.NONE, Key.NONE } /* 5,7 */ }, { /* ROW 6 */ { Key.NUM4, Key.NONE, Key.NONE }, /* 6,0 */ { Key.NUM5, Key.NONE, Key.NONE }, /* 6,1 */ { Key.NUM6, Key.NONE, Key.NONE }, /* 6,2 */ { Key.MULTIPLY, Key.NONE, Key.NONE }, /* 6,3 */ { Key.DIVIDE, Key.NONE, Key.NONE }, /* 6,4 */ { Key.NONE, Key.NONE, Key.NONE }, /* 6,5 */ { Key.NONE, Key.NONE, Key.NONE }, /* 6,6 */ { Key.NONE, Key.NONE, Key.NONE } /* 6,7 */ }, { /* ROW 7 */ { Key.NUM1, Key.NONE, Key.NONE }, /* 7,0 */ { Key.NUM2, Key.NONE, Key.NONE }, /* 7,1 */ { Key.NUM3, Key.NONE, Key.NONE }, /* 7,2 */ { Key.PLUS, Key.PLUS_MINUS, Key.NONE }, /* 7,3 */ { Key.MINUS, Key.NONE, Key.NONE }, /* 7,4 */ { Key.NONE, Key.NONE, Key.NONE }, /* 7,5 */ { Key.NONE, Key.NONE, Key.NONE }, /* 7,6 */ { Key.NONE, Key.NONE, Key.NONE } /* 7,7 */ } }; public static String getKeyName(final int row, final int col) { return Keyboard.getKeyName(row, col, Keyboard.shift, Keyboard.alpha); } public static String getKeyName(final int row, final int col, final boolean shift, final boolean alpha) { final String[] keyValues = Keyboard.KeyLabelsMap[row][col]; if (shift) { if (keyValues[1] != null) { return keyValues[1]; } } else if (alpha) { if (keyValues[2] != null) { return keyValues[2]; } } return keyValues[0]; } public static boolean hasKeyName(final int row, final int col) { final String[] keyValues = Keyboard.KeyLabelsMap[row][col]; if (Keyboard.shift) { return keyValues[1] != null; } else if (Keyboard.alpha) { return keyValues[2] != null; } else { return true; } } /** * * @param row * @param col * @param released true: released, false: pressed */ public static synchronized void keyRaw(final int row, final int col, final boolean released) { // KeyboardDebugScreen.keyX = row; // KeyboardDebugScreen.keyY = col; final Key k = Keyboard.keyMap[row][col][Keyboard.shift ? 1 : Keyboard.alpha ? 2 : 0]; if (k != null) { if (released) { Keyboard.keyReleased(k); } else { Keyboard.keyPressed(k); } } else { if (released) { Keyboard.keyReleased(Key.NONE); } else { Keyboard.keyPressed(Key.NONE); } } } public static void stopKeyboard() { if (WarpPI.getPlatform().isRunningOnRaspberry()) { WarpPI.getPlatform().getGpio().digitalWrite(33, false); WarpPI.getPlatform().getGpio().digitalWrite(35, false); WarpPI.getPlatform().getGpio().digitalWrite(36, false); WarpPI.getPlatform().getGpio().digitalWrite(37, false); WarpPI.getPlatform().getGpio().digitalWrite(38, false); WarpPI.getPlatform().getGpio().digitalWrite(40, false); } } public synchronized static void keyPressed(final Key k) { boolean done = false; if (Keyboard.additionalListener != null) { try { done = Keyboard.additionalListener.onKeyPressed(new KeyPressedEvent(k)); } catch (final Exception ex) { new GUIErrorMessage(ex); } } if (WarpPI.INSTANCE.getHardwareDevice().getDisplayManager() != null) { final Screen scr = WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().getScreen(); boolean refresh = false; boolean scrdone = false; try { scrdone = scr.onKeyPressed(new KeyPressedEvent(k)); } catch (final Exception ex) { new GUIErrorMessage(ex); } if (scr != null && scr.initialized && scrdone) { refresh = true; } else { switch (k) { case POWEROFF: WarpPI.INSTANCE.getHardwareDevice().getDeviceStateDevice().powerOff(); break; case NONE: break; case BRIGHTNESS_CYCLE: WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().setScreen(new TetrisScreen()); //TODO: rimuovere: prova WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().cycleBrightness(false); refresh = true; break; case BRIGHTNESS_CYCLE_REVERSE: WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().setScreen(new MarioScreen()); //TODO: rimuovere: prova WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().cycleBrightness(true); refresh = true; break; case ZOOM_MODE: final float newZoom = StaticVars.windowZoom.getLastValue() % 3 + 1; StaticVars.windowZoom.submit(newZoom); WarpPI.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "Keyboard", "Zoom: " + newZoom); // StaticVars.windowZoom = ((StaticVars.windowZoom - 0.5f) % 2f) + 1f; refresh = true; break; case HISTORY_BACK: WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().goBack(); refresh = true; break; case HISTORY_FORWARD: WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().goForward(); refresh = true; break; case BACK: WarpPI.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "Closing current screen."); WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().closeScreen(); refresh = true; break; default: break; } } switch (k) { case SHIFT: if (Keyboard.alpha) { WarpPI.getPlatform().alphaChanged(Keyboard.alpha = false); } WarpPI.getPlatform().shiftChanged(Keyboard.shift = !Keyboard.shift); refresh = true; break; case ALPHA: if (Keyboard.shift) { WarpPI.getPlatform().shiftChanged(Keyboard.shift = false); } WarpPI.getPlatform().alphaChanged(Keyboard.alpha = !Keyboard.alpha); refresh = true; break; default: if (k != Key.NONE) { if (Keyboard.shift) { WarpPI.getPlatform().shiftChanged(Keyboard.shift = false); } if (Keyboard.alpha) { WarpPI.getPlatform().alphaChanged(Keyboard.alpha = false); } } break; } if (refresh) { Keyboard.refreshRequest = true; } } else if (!done) { WarpPI.getPlatform().getConsoleUtils().out().println(1, "Key " + k.toString() + " ignored."); } } public synchronized static void keyReleased(final Key k) { boolean done = false; if (Keyboard.additionalListener != null) { done = Keyboard.additionalListener.onKeyReleased(new KeyReleasedEvent(k)); } boolean refresh = false; if (WarpPI.INSTANCE.getHardwareDevice().getDisplayManager() != null) { final Screen scr = WarpPI.INSTANCE.getHardwareDevice().getDisplayManager().getScreen(); if (scr != null && scr.initialized && scr.onKeyReleased(new KeyReleasedEvent(k))) { refresh = true; } else { switch (k) { case NONE: break; default: break; } } if (refresh) { Keyboard.refreshRequest = true; } } else if (!done) { WarpPI.getPlatform().getConsoleUtils().out().println(1, "Key " + k.toString() + " ignored."); } } public void setAdditionalKeyboardListener(final KeyboardEventListener l) { Keyboard.additionalListener = l; } public static boolean popRefreshRequest() { if (Keyboard.refreshRequest) { Keyboard.refreshRequest = false; return true; } return false; } } /* Keyboard: Example button: |ROW,COLUMN----| | NORMAL STATE | | SHIFT STATE | | ALPHA STATE | |--------------| Physical keyboard: |0,0-----|0,1-----|########|0,3-----|########|0,5-----|0,6-----| | SHIFT | ALPHA |########| ^ |########|SETTINGS|+BRIGHT | | NORMAL | ALPHA |########| |########| |-BRIGHT | | SHIFT | NORMAL |########| |########| |ZOOMMODE| |1,0-----|1,1-----|1,2-----|1,3-----|1,4-----|1,5-----|1,6-----| | F_4 | | < | OK | > | Back | Fwd | | F_4 | | | | | | | | F_4 | | | | | | | |2,0-----|2,1-----|--------|2,3-----|--------|2,5-----|2,6-----| | F_3 | SQRT |########| v | BACK | | | | F_3 | ROOT |########| | | | | | F_3 | |########| | | | | |3,0-----|3,1-----|3,2-----|3,3-----|3,4-----|3,5-----|3,6-----| | F_2 | | POW x | POW 2 | | | | | F_2 | | | | | | | | F_2 | | | | | | | |4,0-----|4,1-----|4,2-----|4,3-----|4,4-----|4,5-----|4,6-----| | F_1 | | ( | ) | | S<=>D | | | F_1 | | | | | | | | F_1 | | | | | | | |5,0-----|5,1-----|5,2-----|5,3-----|5,4-----|5,5-----|5,6-----| | 7 | 8 | 9 | DEL | RESET | | | | | | | | | | | | | |6,0-----|6,1-----|6,2-----|6,3-----|6,4-----------------------| | 4 | 5 | 6 | * | / | | | | | | | | | | | | | |7,0-----|7,1-----|7,2-----|7,3-----|7,4-----------------------| | 1 | 2 | 3 | + | - | | | | | | | | | | | | | |4,7-----|3,7-----|2,7-----|1,7-----|0,7-----------------------| | 0 | . | | | SIMPLIFY | | | | |PI | STEP | | X | Y | Z |DRG CYCL| | |--------|--------|--------|--------|--------------------------| SCREEN F_n: MathInputScreen: Default: [F_1] Normal: Solve for X Shift: Solve for _ Alpha: [F_2] Normal: Shift: Alpha: [F_3] Normal: Variables & constants Shift: Alpha: [F_4] Normal: Functions f(x) Shift: Alpha: Variable popup: [F_1] Normal(if constant):Set value Shift: Alpha: [F_2] Normal: Shift: Alpha: [F_3] Normal: Shift: Alpha: [F_4] Normal: Shift: Alpha: MarioScreen [F_1] Normal: Shift: Alpha: [F_2] Normal: Shift: Alpha: [F_3] Normal: Shift: Alpha: [F_4] Normal: Shift: Alpha: ChooseVariableValueScreen [F_1] Normal: Shift: Alpha: [F_2] Normal: Shift: Alpha: [F_3] Normal: Shift: Alpha: [F_4] Normal: Shift: Alpha: SolveForXScreen [F_1] Normal: Shift: Alpha: [F_2] Normal: Shift: Alpha: [F_3] Normal: Shift: Alpha: [F_4] Normal: Shift: Alpha: */