/** * Copyright (c) 2010 Marc A. Paradise * * This file is part of "BBSSH" * * BBSSH is based upon MidpSSH by Karl von Randow. * MidpSSH was based upon Telnet Floyd and FloydSSH by Radek Polak. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ package org.bbssh.terminal; import net.rim.device.api.system.KeypadListener; import org.bbssh.model.ConnectionProperties; import org.bbssh.model.FontSettings; import org.bbssh.util.Logger; /** * SImple data object for tracking terminal state. * * @author marc */ public class TerminalStateData { public static final byte TYPING_MODE_SELECT = 3; public static final byte TYPING_MODE_LOCAL_SCROLL = 2; public static final byte TYPING_MODE_HYBRID = 1; public static final byte TYPING_MODE_DIRECT = 0; // accelerometer orientation info - reference 4.7+ Display.ORIENTATION_* // constants public static final int DIRECTION_NORTH = 1; public static final int DIRECTION_EAST = 2; public static final int DIRECTION_WEST = 8; public static final int DIRECTION_ALL = DIRECTION_EAST | DIRECTION_NORTH | DIRECTION_WEST; public static final int DIRECTION_PORTRAIT = 32; public FontSettings fs = null; /** * Session this terminal represents. */ public ConnectionProperties settings; /** * What's the orientation mode for this terminal? (accelerometer support) */ public int orientationMode = DIRECTION_ALL; /** * State flags for device, set temporarily upon processing keystroke event. * Used by mapped handlers. */ public int deviceStateFlags; /** * Update this to indicate if the next keypress should be submitted masked * with the "ALT" keypress. */ public boolean altPressed; /** * Update this to indicate if the next keypress shoudl be submitted masked * with the "CTRL" keypress */ public boolean ctrlPressed; /** * Update this to change the typing mode using the appropriate TYPING_MODE_* * const */ public int typingMode; /** * Top-most row current visible. */ public int topTermRow; /** * Left-most position currently visible */ public int left; /** * If true, a change has been made which requires the terminal screen to * refresh/repaint. */ public boolean refreshRequired; /** * Number of rows we can display. */ public int numRows; /** * Number of columns we can display. */ public int numColsVisible; // Maxmimum terminal width public int maxWidth; // Maximum terminal height public int maxHeight; private int artificialStatus; public boolean fullRefreshRequired; public int debugPartialRefreshCount; public int debugFullRefreshCount; public int debugPaintCount; public int debugPaintBackStoreCount; public int debugLinePaintCount; public int debugLineEvalCount; public long debugRedrawRequestWaitTime; public long debugRedrawStartWaitTime; public int selectionCursorX; public int selectionCursorY; boolean externalUpdate = false; public boolean error = false; public boolean notified = false; public boolean suppressNotify = false; private int actualStatus; public TerminalStateData(ConnectionProperties prop) { typingMode = prop.getDefaultInputMode(); settings = prop; fs = new FontSettings(prop.getFontSettings()); } /** * Retrieves a mask of VT320 codes indicating correct key modifiers based on * this state instances "deviceState" field and alt/ctrl flags. * * @param reset * indicates wehther to reset local state (ctrl and alt) to "off" * after calculating the correct flag. Note that device state is * always cleared. * @return VT320 modifier flags based on state data */ public int getModifierKeyState(boolean reset) { int ret = getModifierKeyState(deviceStateFlags, reset); deviceStateFlags = 0; return ret; } /** * Retrieves a mask of VT320 codes indicating correct key modifiers to send * with a keystroke based on provided keypad state. * * @param status * device keypad status mask * @param reset * indicates wehther to reset local state (ctrl and alt) to "off" * after calculating the correct flag. * @return VT320 modifier flags based on state data */ public int getModifierKeyState(int status, boolean reset) { int mode = 0; if ((status & KeypadListener.STATUS_SHIFT) > 0 || (status & KeypadListener.STATUS_SHIFT_LEFT) > 0 || (status & KeypadListener.STATUS_SHIFT_RIGHT) > 0) { mode = VT320.KEY_SHIFT; } if (ctrlPressed) { mode |= VT320.KEY_CONTROL; if (reset) { ctrlPressed = false; } } if (altPressed) { mode |= VT320.KEY_ALT; if (reset) { altPressed = false; } } return mode; } public int getArtificialStatus(boolean reset) { int temp = artificialStatus; if (reset) { artificialStatus = 0; externalUpdate = false; } return temp; } public void toggleArtificialStatus(int status, boolean externalUpdate) { if (!externalUpdate) { // actualStatus = ((actualStatus & status) > 0) ? actualStatus & ~status : actualStatus ^ status; // tracking the physical status state if ((actualStatus & status) > 0) { actualStatus ^= status; } else { } Logger.debug("Actual status: " + actualStatus); status = actualStatus; } artificialStatus = (artificialStatus == 0) ? status : 0; this.externalUpdate = externalUpdate; } public void setArtificialStatus(int status) { actualStatus = 0; // assuming we don't get proper notification when stauts is toggled due to leaving window focus. artificialStatus = status; externalUpdate = false; } public boolean isExternalArtificialStatusUpdate() { return externalUpdate; } }