package test;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import net.rim.device.api.i18n.ResourceBundle;
import net.rim.device.api.i18n.ResourceBundleFamily;
import net.rim.device.api.io.FileNotFoundException;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.container.FullScreen;
import net.rim.device.api.ui.picker.FilePicker;
import org.bbssh.exceptions.FontNotFoundException;
import org.bbssh.i18n.BBSSHResource;
import org.bbssh.model.ConnectionManager;
import org.bbssh.model.ConnectionProperties;
import org.bbssh.model.FontSettings;
import org.bbssh.model.Key;
import org.bbssh.model.SettingsManager;
import org.bbssh.net.session.SessionListener;
import org.bbssh.net.session.TestSession;
import org.bbssh.session.RemoteSessionInstance;
import org.bbssh.session.SessionManager;
import org.bbssh.terminal.TerminalStateData;
import org.bbssh.terminal.VT320;
import org.bbssh.terminal.VT320Debug;
import org.bbssh.terminal.fonts.BBSSHFontManager;
import org.bbssh.terminal.fonts.FontInitializationFailedException;
import org.bbssh.ui.components.TerminalField;
import org.bbssh.ui.components.overlay.OverlayManager;
import org.bbssh.util.Logger;
import org.bbssh.util.Version;
/**
* Simple class that displays MyScreen,w hcih youc an fill with whatever testing
* content you need.
*/
public class MainApp extends UiApplication {
/**
* Main entry point for test app.
*
* @param args
*/
public static void main(String[] args) {
MainApp app = new MainApp();
try {
BBSSHFontManager.initialize();
} catch (FileNotFoundException e) {
Logger.fatal("File not found.", e);
} catch (FontInitializationFailedException e) {
Logger.fatal("Font init failed.", e);
}
app.enterEventDispatcher();
}
/**
* App instance constructor
*/
public MainApp() {
// / pushScreen(new OverlayTestScreen());
pushScreen(new SimpleScreen());
}
}
/**
* Simple test screen. By default, takes an action when nav button is clicked.
*/
class SimpleScreen extends FullScreen implements SessionListener,
FieldChangeListener {
ResourceBundleFamily res = ResourceBundle.getBundle(
BBSSHResource.BUNDLE_ID, BBSSHResource.BUNDLE_NAME);
RemoteSessionInstance inst;
TerminalField term = new TerminalField();
// For now, hard-code a specific connection isntance to use for
// our terminal settings.
// Some basic setup
SettingsManager sm = SettingsManager.getInstance();
ConnectionManager cm = ConnectionManager.getInstance();
boolean stop = false;
boolean running = false;
private final MenuItem start = new MenuItem(res,
BBSSHResource.MENU_CONNECT, 0x00100000, 0) {
public void run() {
if (running)
return;
new Thread(termpump).start();
}
};
private final MenuItem exit = new MenuItem("Exit", 0x00100000, 1) {
public void run() {
stop = true;
UiApplication.getUiApplication().popScreen(SimpleScreen.this);
}
};
private final MenuItem halt = new MenuItem(res,
BBSSHResource.MENU_DISCONNECT, 0x00100000, 1) {
public void run() {
if (!running)
return;
running = false;
stop = true;
}
};
private OverlayManager overlayManager;
private DataInputStream indexIn;
private DataInputStream dataIn;
FileConnection fconn;
RemoteSessionInstance rsi = new RemoteSessionInstance();
public void close() {
closeStuff();
}
Runnable termpump = new Runnable() {
protected boolean utf8;
private short speedFactor = 10;
String fileName;
long offset;
// private long startTime;
private ConnectionProperties readProperties() throws IOException {
byte event;
ConnectionProperties prop = new ConnectionProperties(false);
prop.setName("Session Replay");
while ((event = indexIn.readByte()) != VT320Debug.EVENT_INIT_DONE) {
switch (event) {
case VT320Debug.EVENT_TERMATTR_COLORS:
prop.setBackgroundColorIndex(indexIn.readInt());
prop.setForegroundColorIndex(indexIn.readInt());
break;
case VT320Debug.EVENT_TERMATTR_FONT:
prop.setFontSettings(new FontSettings(indexIn.readByte(),
indexIn.readByte(), indexIn.readByte()));
break;
case VT320Debug.EVENT_MARKER:
// startTime = indexIn.readLong();
break;
}
}
// params to init done that we don't use.
utf8 = indexIn.readInt() == 1;
indexIn.readInt();
return prop;
}
public void run() {
running = true;
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
FilePicker picker = FilePicker.getInstance();
picker.setPath("file:///SDCard/");
picker.setFilter(".txt");
fileName = picker.show();
if (fileName == null) {
running = false;
}
// updateLayout();
}
});
if (!running)
return;
// sloppy sloppy...
try {
String indexName = fileName.substring(0,
fileName.lastIndexOf('.') + 1)
+ "idx";
FileConnection fconn = (FileConnection) Connector
.open(indexName);
indexIn = fconn.openDataInputStream();
fconn.close();
fconn = (FileConnection) Connector.open(fileName);
dataIn = fconn.openDataInputStream();
fconn.close();
ConnectionProperties prop = readProperties();
rsi.state = new TerminalStateData(prop);
rsi.session = new TestSession(prop, 0,
(SessionListener) SimpleScreen.this);
SessionManager.getInstance().activeSession = rsi;
// @todo why do we not use a single emulator source?
rsi.emulator = rsi.session.getEmulator();
try {
term.attachInstance(rsi);
} catch (FontNotFoundException e1) {
Logger.error("Unable to load font.");
return;
}
} catch (Exception e) {
running = false;
System.out.println("Abort due to IOException: "
+ e.getMessage());
closeStuff();
return;
}
int delay;
int count = 0;
long last = System.currentTimeMillis();
try {
VT320 emulator = rsi.session.getEmulator();
while (!stop) {
switch (indexIn.readByte()) {
case VT320Debug.EVENT_COMMENT:
term.showExpiringMessage(indexIn.readUTF());
continue;
case VT320Debug.EVENT_MARKER:
term.showExpiringMessage("User Mark @ " + offset + " ("
+ count + ")");
// @todo auto pause on mark option. or readahead and
// auto slow donw on approach?
continue;
case VT320Debug.EVENT_TERMATTR_FONT:
// @todo clean this up in main app - fs should be RSI
// level perhaps? not state? Why seprate
// updateFontSettings w/ arg?
rsi.state.fs = new FontSettings(indexIn.readByte(),
indexIn.readByte(), indexIn.readByte());
term.updateFontSettings(rsi.state.fs);
continue;
case VT320Debug.EVENT_TERMATTR_SIZE:
emulator.setScreenSize(indexIn.readInt(),
indexIn.readInt(), false);
continue;
case VT320Debug.EVENT_TERMATTR_SCROLLBACK:
emulator.setScrollbackBufferSize(indexIn.readInt());
continue;
case VT320Debug.EVENT_TERMATTR_TYPE:
emulator.setTerminalID(indexIn.readUTF());
continue;
case VT320Debug.EVENT_DATA:
break;
}
count++;
delay = indexIn.readInt();
offset += delay;
if (delay > 150 || System.currentTimeMillis() - last > 500) {
last = System.currentTimeMillis();
// safe bet that if 150 ms pass w/ no input, we're
// pausing long enough that a csreen update would have
// occurred normally.
emulator.refreshCursorPosition();
term.redraw(false);
} else if (delay > speedFactor) {
try {
Thread.sleep(delay / speedFactor);
} catch (InterruptedException e) {
stop = true;
System.out
.println("Unexpected interruption, aborting.");
return;
}
}
emulator.putChar(
utf8 ? dataIn.readChar() : (char) dataIn.read(),
false);
}
emulator.refreshCursorPosition();
term.redraw(false);
} catch (EOFException e) {
Logger.info("Completed playback.");
} catch (IOException e) {
Logger.fatal("Unexpected ioexception.");
} catch (FontNotFoundException e) {
Logger.fatal("Changed font, but not not valid.");
} finally {
closeStuff();
running = false;
}
// Close the terminal
}
};
public SimpleScreen() {
super(new OverlayManager(), DEFAULT_MENU);
String name = TerminalField.class.getName();
term = (TerminalField) Version.createOSObjectInstance(name);
overlayManager = (OverlayManager) getDelegate();
overlayManager.setChangeListener(this);
overlayManager.setCentralField(term);
}
protected void makeMenu(net.rim.device.api.ui.component.Menu menu,
int instance) {
super.makeMenu(menu, instance);
menu.add(halt);
menu.add(start);
menu.add(exit);
}
public boolean isDirty() {
return false;
}
protected void sublayout(int width, int height) {
super.sublayout(width, height);
term.sizeChanged(false);
}
public void onSessionConnected(int sessionId) {
}
public void onSessionDisconnected(int sessionId, int bytesWritten,
int bytesRead) {
}
public void onSessionError(int sessionId, String errorMessage) {
}
public void onSessionRemoteAlert(int sessionId) {
}
public String getKeyPassword(int sessionId, Key key) {
return null;
}
public void onDisplayDirty(int sessionId) {
term.redraw(false);
}
public void onDisplayInvalid(int sessionId) {
term.redraw(true);
}
public void fieldChanged(Field arg0, int arg1) {
// TODO Auto-generated method stub
}
protected void closeStuff() {
try {
if (dataIn != null)
dataIn.close();
dataIn = null;
} catch (IOException e) {
}
try {
if (indexIn != null)
indexIn.close();
indexIn = null;
} catch (IOException e) {
}
}
}