Almost implement XVnc
BIN
app/libs/com.antlersoft.android.contentxml.jar
Normal file
BIN
app/libs/com.antlersoft.android.db.jar
Normal file
@@ -55,6 +55,12 @@
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:name=".prefs.LauncherPreferenceActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"/>
|
||||
|
||||
<!-- VNC Activity -->
|
||||
<activity
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:name="android.androidVNC.VncCanvasActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
171
app/src/main/java/android/androidVNC/AbstractBitmapData.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.widget.ImageView;
|
||||
|
||||
/**
|
||||
* Abstract interface between the VncCanvas and the bitmap and pixel data buffers that actually contain
|
||||
* the data.
|
||||
* This allows for implementations that use smaller bitmaps or buffers to save memory.
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
abstract class AbstractBitmapData {
|
||||
int framebufferwidth;
|
||||
int framebufferheight;
|
||||
int bitmapwidth;
|
||||
int bitmapheight;
|
||||
RfbProto rfb;
|
||||
Bitmap mbitmap;
|
||||
int bitmapPixels[];
|
||||
Canvas memGraphics;
|
||||
boolean waitingForInput;
|
||||
VncCanvas vncCanvas;
|
||||
private AbstractBitmapDrawable drawable;
|
||||
|
||||
AbstractBitmapData( RfbProto p, VncCanvas c)
|
||||
{
|
||||
rfb=p;
|
||||
vncCanvas = c;
|
||||
framebufferwidth=rfb.framebufferWidth;
|
||||
framebufferheight=rfb.framebufferHeight;
|
||||
}
|
||||
|
||||
synchronized void doneWaiting()
|
||||
{
|
||||
waitingForInput=false;
|
||||
}
|
||||
|
||||
final void invalidateMousePosition()
|
||||
{
|
||||
if (vncCanvas.connection.getUseLocalCursor())
|
||||
{
|
||||
if (drawable==null)
|
||||
drawable = createDrawable();
|
||||
drawable.setCursorRect(vncCanvas.mouseX,vncCanvas.mouseY);
|
||||
vncCanvas.invalidate(drawable.cursorRect);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The smallest scale supported by the implementation; the scale at which
|
||||
* the bitmap would be smaller than the screen
|
||||
*/
|
||||
float getMinimumScale()
|
||||
{
|
||||
double scale = 0.75;
|
||||
int displayWidth = vncCanvas.getWidth();
|
||||
int displayHeight = vncCanvas.getHeight();
|
||||
for (; scale >= 0; scale -= 0.25)
|
||||
{
|
||||
if (scale * bitmapwidth < displayWidth || scale * bitmapheight < displayHeight)
|
||||
break;
|
||||
}
|
||||
return (float)(scale + 0.25);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request through the protocol to get the data for the currently held bitmap
|
||||
* @param incremental True if we want incremental update; false for full update
|
||||
*/
|
||||
abstract void writeFullUpdateRequest( boolean incremental) throws IOException;
|
||||
|
||||
/**
|
||||
* Determine if a rectangle in full-frame coordinates can be drawn in the existing buffer
|
||||
* @param x Top left x
|
||||
* @param y Top left y
|
||||
* @param w width (pixels)
|
||||
* @param h height (pixels)
|
||||
* @return True if entire rectangle fits into current screen buffer, false otherwise
|
||||
*/
|
||||
abstract boolean validDraw( int x, int y, int w, int h);
|
||||
|
||||
/**
|
||||
* Return an offset in the bitmapPixels array of a point in full-frame coordinates
|
||||
* @param x
|
||||
* @param y
|
||||
* @return Offset in bitmapPixels array of color data for that point
|
||||
*/
|
||||
abstract int offset( int x, int y);
|
||||
|
||||
/**
|
||||
* Update pixels in the bitmap with data from the bitmapPixels array, positioned
|
||||
* in full-frame coordinates
|
||||
* @param x Top left x
|
||||
* @param y Top left y
|
||||
* @param w width (pixels)
|
||||
* @param h height (pixels)
|
||||
*/
|
||||
abstract void updateBitmap( int x, int y, int w, int h);
|
||||
|
||||
/**
|
||||
* Create drawable appropriate for this data
|
||||
* @return drawable
|
||||
*/
|
||||
abstract AbstractBitmapDrawable createDrawable();
|
||||
|
||||
/**
|
||||
* Call in UI thread; tell ImageView we've changed
|
||||
* @param v ImageView displaying bitmap data
|
||||
*/
|
||||
void updateView(ImageView v)
|
||||
{
|
||||
if (drawable==null)
|
||||
drawable = createDrawable();
|
||||
v.setImageDrawable(drawable);
|
||||
v.invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a rectangle from one part of the bitmap to another
|
||||
* @param src Rectangle in full-frame coordinates to be copied
|
||||
* @param dest Destination rectangle in full-frame coordinates
|
||||
* @param paint Paint specifier
|
||||
*/
|
||||
abstract void copyRect( Rect src, Rect dest, Paint paint);
|
||||
|
||||
/**
|
||||
* Draw a rectangle in the bitmap with coordinates given in full frame
|
||||
* @param x Top left x
|
||||
* @param y Top left y
|
||||
* @param w width (pixels)
|
||||
* @param h height (pixels)
|
||||
* @param paint How to draw
|
||||
*/
|
||||
abstract void drawRect( int x, int y, int w, int h, Paint paint);
|
||||
|
||||
/**
|
||||
* Scroll position has changed.
|
||||
* <p>
|
||||
* This method is called in the UI thread-- it updates internal status, but does
|
||||
* not change the bitmap data or send a network request until syncScroll is called
|
||||
* @param newx Position of left edge of visible part in full-frame coordinates
|
||||
* @param newy Position of top edge of visible part in full-frame coordinates
|
||||
*/
|
||||
abstract void scrollChanged( int newx, int newy);
|
||||
|
||||
/**
|
||||
* Sync scroll -- called from network thread; copies scroll changes from UI to network state
|
||||
*/
|
||||
abstract void syncScroll();
|
||||
|
||||
/**
|
||||
* Release resources
|
||||
*/
|
||||
void dispose()
|
||||
{
|
||||
if ( mbitmap!=null )
|
||||
mbitmap.recycle();
|
||||
memGraphics = null;
|
||||
bitmapPixels = null;
|
||||
}
|
||||
}
|
||||
100
app/src/main/java/android/androidVNC/AbstractBitmapDrawable.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.DrawableContainer;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
public class AbstractBitmapDrawable extends DrawableContainer {
|
||||
Rect cursorRect;
|
||||
Rect clipRect;
|
||||
|
||||
AbstractBitmapData data;
|
||||
|
||||
static final Paint _defaultPaint;
|
||||
static final Paint _whitePaint;
|
||||
static final Paint _blackPaint;
|
||||
|
||||
static {
|
||||
_defaultPaint = new Paint();
|
||||
_whitePaint = new Paint();
|
||||
_whitePaint.setColor(0xffffffff);
|
||||
_blackPaint = new Paint();
|
||||
_blackPaint.setColor(0xff000000);
|
||||
}
|
||||
|
||||
AbstractBitmapDrawable(AbstractBitmapData data)
|
||||
{
|
||||
this.data = data;
|
||||
cursorRect = new Rect();
|
||||
clipRect = new Rect();
|
||||
}
|
||||
|
||||
void draw(Canvas canvas, int xoff, int yoff)
|
||||
{
|
||||
canvas.drawBitmap(data.mbitmap, xoff, yoff, _defaultPaint);
|
||||
if(data.vncCanvas.connection.getUseLocalCursor())
|
||||
{
|
||||
setCursorRect(data.vncCanvas.mouseX, data.vncCanvas.mouseY);
|
||||
clipRect.set(cursorRect);
|
||||
if (canvas.clipRect(cursorRect))
|
||||
{
|
||||
drawCursor(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawCursor(Canvas canvas)
|
||||
{
|
||||
canvas.drawRect(cursorRect,_whitePaint);
|
||||
canvas.drawRect((float)cursorRect.left + 1, (float)cursorRect.top + 1, (float)cursorRect.right - 1, (float)cursorRect.bottom - 1, _blackPaint);
|
||||
}
|
||||
|
||||
void setCursorRect(int mouseX, int mouseY)
|
||||
{
|
||||
cursorRect.left = mouseX - 2;
|
||||
cursorRect.right = cursorRect.left + 4;
|
||||
cursorRect.top = mouseY - 2;
|
||||
cursorRect.bottom = cursorRect.top + 4;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.graphics.drawable.DrawableContainer#getIntrinsicHeight()
|
||||
*/
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return data.framebufferheight;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.graphics.drawable.DrawableContainer#getIntrinsicWidth()
|
||||
*/
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return data.framebufferwidth;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.graphics.drawable.DrawableContainer#getOpacity()
|
||||
*/
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.OPAQUE;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.graphics.drawable.DrawableContainer#isStateful()
|
||||
*/
|
||||
@Override
|
||||
public boolean isStateful() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
305
app/src/main/java/android/androidVNC/AbstractConnectionBean.java
Normal file
@@ -0,0 +1,305 @@
|
||||
// This class was generated from android.androidVNC.IConnectionBean by a tool
|
||||
// Do not edit this file directly! PLX THX
|
||||
package android.androidVNC;
|
||||
|
||||
public abstract class AbstractConnectionBean extends com.antlersoft.android.dbimpl.IdImplementationBase implements IConnectionBean {
|
||||
|
||||
public static final String GEN_TABLE_NAME = "CONNECTION_BEAN";
|
||||
public static final int GEN_COUNT = 21;
|
||||
|
||||
// Field constants
|
||||
public static final String GEN_FIELD__ID = "_id";
|
||||
public static final int GEN_ID__ID = 0;
|
||||
public static final String GEN_FIELD_NICKNAME = "NICKNAME";
|
||||
public static final int GEN_ID_NICKNAME = 1;
|
||||
public static final String GEN_FIELD_ADDRESS = "ADDRESS";
|
||||
public static final int GEN_ID_ADDRESS = 2;
|
||||
public static final String GEN_FIELD_PORT = "PORT";
|
||||
public static final int GEN_ID_PORT = 3;
|
||||
public static final String GEN_FIELD_PASSWORD = "PASSWORD";
|
||||
public static final int GEN_ID_PASSWORD = 4;
|
||||
public static final String GEN_FIELD_COLORMODEL = "COLORMODEL";
|
||||
public static final int GEN_ID_COLORMODEL = 5;
|
||||
public static final String GEN_FIELD_FORCEFULL = "FORCEFULL";
|
||||
public static final int GEN_ID_FORCEFULL = 6;
|
||||
public static final String GEN_FIELD_REPEATERID = "REPEATERID";
|
||||
public static final int GEN_ID_REPEATERID = 7;
|
||||
public static final String GEN_FIELD_INPUTMODE = "INPUTMODE";
|
||||
public static final int GEN_ID_INPUTMODE = 8;
|
||||
public static final String GEN_FIELD_SCALEMODE = "SCALEMODE";
|
||||
public static final int GEN_ID_SCALEMODE = 9;
|
||||
public static final String GEN_FIELD_USELOCALCURSOR = "USELOCALCURSOR";
|
||||
public static final int GEN_ID_USELOCALCURSOR = 10;
|
||||
public static final String GEN_FIELD_KEEPPASSWORD = "KEEPPASSWORD";
|
||||
public static final int GEN_ID_KEEPPASSWORD = 11;
|
||||
public static final String GEN_FIELD_FOLLOWMOUSE = "FOLLOWMOUSE";
|
||||
public static final int GEN_ID_FOLLOWMOUSE = 12;
|
||||
public static final String GEN_FIELD_USEREPEATER = "USEREPEATER";
|
||||
public static final int GEN_ID_USEREPEATER = 13;
|
||||
public static final String GEN_FIELD_METALISTID = "METALISTID";
|
||||
public static final int GEN_ID_METALISTID = 14;
|
||||
public static final String GEN_FIELD_LAST_META_KEY_ID = "LAST_META_KEY_ID";
|
||||
public static final int GEN_ID_LAST_META_KEY_ID = 15;
|
||||
public static final String GEN_FIELD_FOLLOWPAN = "FOLLOWPAN";
|
||||
public static final int GEN_ID_FOLLOWPAN = 16;
|
||||
public static final String GEN_FIELD_USERNAME = "USERNAME";
|
||||
public static final int GEN_ID_USERNAME = 17;
|
||||
public static final String GEN_FIELD_SECURECONNECTIONTYPE = "SECURECONNECTIONTYPE";
|
||||
public static final int GEN_ID_SECURECONNECTIONTYPE = 18;
|
||||
public static final String GEN_FIELD_SHOWZOOMBUTTONS = "SHOWZOOMBUTTONS";
|
||||
public static final int GEN_ID_SHOWZOOMBUTTONS = 19;
|
||||
public static final String GEN_FIELD_DOUBLE_TAP_ACTION = "DOUBLE_TAP_ACTION";
|
||||
public static final int GEN_ID_DOUBLE_TAP_ACTION = 20;
|
||||
|
||||
// SQL Command for creating the table
|
||||
public static String GEN_CREATE = "CREATE TABLE CONNECTION_BEAN (" +
|
||||
"_id INTEGER PRIMARY KEY AUTOINCREMENT," +
|
||||
"NICKNAME TEXT," +
|
||||
"ADDRESS TEXT," +
|
||||
"PORT INTEGER," +
|
||||
"PASSWORD TEXT," +
|
||||
"COLORMODEL TEXT," +
|
||||
"FORCEFULL INTEGER," +
|
||||
"REPEATERID TEXT," +
|
||||
"INPUTMODE TEXT," +
|
||||
"SCALEMODE TEXT," +
|
||||
"USELOCALCURSOR INTEGER," +
|
||||
"KEEPPASSWORD INTEGER," +
|
||||
"FOLLOWMOUSE INTEGER," +
|
||||
"USEREPEATER INTEGER," +
|
||||
"METALISTID INTEGER," +
|
||||
"LAST_META_KEY_ID INTEGER," +
|
||||
"FOLLOWPAN INTEGER DEFAULT 0," +
|
||||
"USERNAME TEXT," +
|
||||
"SECURECONNECTIONTYPE TEXT," +
|
||||
"SHOWZOOMBUTTONS INTEGER DEFAULT 1," +
|
||||
"DOUBLE_TAP_ACTION TEXT" +
|
||||
")";
|
||||
|
||||
// Members corresponding to defined fields
|
||||
private long gen__Id;
|
||||
private java.lang.String gen_nickname;
|
||||
private java.lang.String gen_address;
|
||||
private int gen_port;
|
||||
private java.lang.String gen_password;
|
||||
private java.lang.String gen_colorModel;
|
||||
private long gen_forceFull;
|
||||
private java.lang.String gen_repeaterId;
|
||||
private java.lang.String gen_inputMode;
|
||||
private java.lang.String gen_SCALEMODE;
|
||||
private boolean gen_useLocalCursor;
|
||||
private boolean gen_keepPassword;
|
||||
private boolean gen_followMouse;
|
||||
private boolean gen_useRepeater;
|
||||
private long gen_metaListId;
|
||||
private long gen_LAST_META_KEY_ID;
|
||||
private boolean gen_followPan;
|
||||
private java.lang.String gen_userName;
|
||||
private java.lang.String gen_secureConnectionType;
|
||||
private boolean gen_showZoomButtons;
|
||||
private java.lang.String gen_DOUBLE_TAP_ACTION;
|
||||
|
||||
|
||||
public String Gen_tableName() { return GEN_TABLE_NAME; }
|
||||
|
||||
// Field accessors
|
||||
public long get_Id() { return gen__Id; }
|
||||
public void set_Id(long arg__Id) { gen__Id = arg__Id; }
|
||||
public java.lang.String getNickname() { return gen_nickname; }
|
||||
public void setNickname(java.lang.String arg_nickname) { gen_nickname = arg_nickname; }
|
||||
public java.lang.String getAddress() { return gen_address; }
|
||||
public void setAddress(java.lang.String arg_address) { gen_address = arg_address; }
|
||||
public int getPort() { return gen_port; }
|
||||
public void setPort(int arg_port) { gen_port = arg_port; }
|
||||
public java.lang.String getPassword() { return gen_password; }
|
||||
public void setPassword(java.lang.String arg_password) { gen_password = arg_password; }
|
||||
public java.lang.String getColorModel() { return gen_colorModel; }
|
||||
public void setColorModel(java.lang.String arg_colorModel) { gen_colorModel = arg_colorModel; }
|
||||
public long getForceFull() { return gen_forceFull; }
|
||||
public void setForceFull(long arg_forceFull) { gen_forceFull = arg_forceFull; }
|
||||
public java.lang.String getRepeaterId() { return gen_repeaterId; }
|
||||
public void setRepeaterId(java.lang.String arg_repeaterId) { gen_repeaterId = arg_repeaterId; }
|
||||
public java.lang.String getInputMode() { return gen_inputMode; }
|
||||
public void setInputMode(java.lang.String arg_inputMode) { gen_inputMode = arg_inputMode; }
|
||||
public java.lang.String getScaleModeAsString() { return gen_SCALEMODE; }
|
||||
public void setScaleModeAsString(java.lang.String arg_SCALEMODE) { gen_SCALEMODE = arg_SCALEMODE; }
|
||||
public boolean getUseLocalCursor() { return gen_useLocalCursor; }
|
||||
public void setUseLocalCursor(boolean arg_useLocalCursor) { gen_useLocalCursor = arg_useLocalCursor; }
|
||||
public boolean getKeepPassword() { return gen_keepPassword; }
|
||||
public void setKeepPassword(boolean arg_keepPassword) { gen_keepPassword = arg_keepPassword; }
|
||||
public boolean getFollowMouse() { return gen_followMouse; }
|
||||
public void setFollowMouse(boolean arg_followMouse) { gen_followMouse = arg_followMouse; }
|
||||
public boolean getUseRepeater() { return gen_useRepeater; }
|
||||
public void setUseRepeater(boolean arg_useRepeater) { gen_useRepeater = arg_useRepeater; }
|
||||
public long getMetaListId() { return gen_metaListId; }
|
||||
public void setMetaListId(long arg_metaListId) { gen_metaListId = arg_metaListId; }
|
||||
public long getLastMetaKeyId() { return gen_LAST_META_KEY_ID; }
|
||||
public void setLastMetaKeyId(long arg_LAST_META_KEY_ID) { gen_LAST_META_KEY_ID = arg_LAST_META_KEY_ID; }
|
||||
public boolean getFollowPan() { return gen_followPan; }
|
||||
public void setFollowPan(boolean arg_followPan) { gen_followPan = arg_followPan; }
|
||||
public java.lang.String getUserName() { return gen_userName; }
|
||||
public void setUserName(java.lang.String arg_userName) { gen_userName = arg_userName; }
|
||||
public java.lang.String getSecureConnectionType() { return gen_secureConnectionType; }
|
||||
public void setSecureConnectionType(java.lang.String arg_secureConnectionType) { gen_secureConnectionType = arg_secureConnectionType; }
|
||||
public boolean getShowZoomButtons() { return gen_showZoomButtons; }
|
||||
public void setShowZoomButtons(boolean arg_showZoomButtons) { gen_showZoomButtons = arg_showZoomButtons; }
|
||||
public java.lang.String getDoubleTapActionAsString() { return gen_DOUBLE_TAP_ACTION; }
|
||||
public void setDoubleTapActionAsString(java.lang.String arg_DOUBLE_TAP_ACTION) { gen_DOUBLE_TAP_ACTION = arg_DOUBLE_TAP_ACTION; }
|
||||
|
||||
public android.content.ContentValues Gen_getValues() {
|
||||
android.content.ContentValues values=new android.content.ContentValues();
|
||||
values.put(GEN_FIELD__ID,Long.toString(this.gen__Id));
|
||||
values.put(GEN_FIELD_NICKNAME,this.gen_nickname);
|
||||
values.put(GEN_FIELD_ADDRESS,this.gen_address);
|
||||
values.put(GEN_FIELD_PORT,Integer.toString(this.gen_port));
|
||||
values.put(GEN_FIELD_PASSWORD,this.gen_password);
|
||||
values.put(GEN_FIELD_COLORMODEL,this.gen_colorModel);
|
||||
values.put(GEN_FIELD_FORCEFULL,Long.toString(this.gen_forceFull));
|
||||
values.put(GEN_FIELD_REPEATERID,this.gen_repeaterId);
|
||||
values.put(GEN_FIELD_INPUTMODE,this.gen_inputMode);
|
||||
values.put(GEN_FIELD_SCALEMODE,this.gen_SCALEMODE);
|
||||
values.put(GEN_FIELD_USELOCALCURSOR,(this.gen_useLocalCursor ? "1" : "0"));
|
||||
values.put(GEN_FIELD_KEEPPASSWORD,(this.gen_keepPassword ? "1" : "0"));
|
||||
values.put(GEN_FIELD_FOLLOWMOUSE,(this.gen_followMouse ? "1" : "0"));
|
||||
values.put(GEN_FIELD_USEREPEATER,(this.gen_useRepeater ? "1" : "0"));
|
||||
values.put(GEN_FIELD_METALISTID,Long.toString(this.gen_metaListId));
|
||||
values.put(GEN_FIELD_LAST_META_KEY_ID,Long.toString(this.gen_LAST_META_KEY_ID));
|
||||
values.put(GEN_FIELD_FOLLOWPAN,(this.gen_followPan ? "1" : "0"));
|
||||
values.put(GEN_FIELD_USERNAME,this.gen_userName);
|
||||
values.put(GEN_FIELD_SECURECONNECTIONTYPE,this.gen_secureConnectionType);
|
||||
values.put(GEN_FIELD_SHOWZOOMBUTTONS,(this.gen_showZoomButtons ? "1" : "0"));
|
||||
values.put(GEN_FIELD_DOUBLE_TAP_ACTION,this.gen_DOUBLE_TAP_ACTION);
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array that gives the column index in the cursor for each field defined
|
||||
* @param cursor Database cursor over some columns, possibly including this table
|
||||
* @return array of column indices; -1 if the column with that id is not in cursor
|
||||
*/
|
||||
public int[] Gen_columnIndices(android.database.Cursor cursor) {
|
||||
int[] result=new int[GEN_COUNT];
|
||||
result[0] = cursor.getColumnIndex(GEN_FIELD__ID);
|
||||
// Make compatible with database generated by older version of plugin with uppercase column name
|
||||
if (result[0] == -1) {
|
||||
result[0] = cursor.getColumnIndex("_ID");
|
||||
}
|
||||
result[1] = cursor.getColumnIndex(GEN_FIELD_NICKNAME);
|
||||
result[2] = cursor.getColumnIndex(GEN_FIELD_ADDRESS);
|
||||
result[3] = cursor.getColumnIndex(GEN_FIELD_PORT);
|
||||
result[4] = cursor.getColumnIndex(GEN_FIELD_PASSWORD);
|
||||
result[5] = cursor.getColumnIndex(GEN_FIELD_COLORMODEL);
|
||||
result[6] = cursor.getColumnIndex(GEN_FIELD_FORCEFULL);
|
||||
result[7] = cursor.getColumnIndex(GEN_FIELD_REPEATERID);
|
||||
result[8] = cursor.getColumnIndex(GEN_FIELD_INPUTMODE);
|
||||
result[9] = cursor.getColumnIndex(GEN_FIELD_SCALEMODE);
|
||||
result[10] = cursor.getColumnIndex(GEN_FIELD_USELOCALCURSOR);
|
||||
result[11] = cursor.getColumnIndex(GEN_FIELD_KEEPPASSWORD);
|
||||
result[12] = cursor.getColumnIndex(GEN_FIELD_FOLLOWMOUSE);
|
||||
result[13] = cursor.getColumnIndex(GEN_FIELD_USEREPEATER);
|
||||
result[14] = cursor.getColumnIndex(GEN_FIELD_METALISTID);
|
||||
result[15] = cursor.getColumnIndex(GEN_FIELD_LAST_META_KEY_ID);
|
||||
result[16] = cursor.getColumnIndex(GEN_FIELD_FOLLOWPAN);
|
||||
result[17] = cursor.getColumnIndex(GEN_FIELD_USERNAME);
|
||||
result[18] = cursor.getColumnIndex(GEN_FIELD_SECURECONNECTIONTYPE);
|
||||
result[19] = cursor.getColumnIndex(GEN_FIELD_SHOWZOOMBUTTONS);
|
||||
result[20] = cursor.getColumnIndex(GEN_FIELD_DOUBLE_TAP_ACTION);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate one instance from a cursor
|
||||
*/
|
||||
public void Gen_populate(android.database.Cursor cursor,int[] columnIndices) {
|
||||
if ( columnIndices[GEN_ID__ID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID__ID])) {
|
||||
gen__Id = cursor.getLong(columnIndices[GEN_ID__ID]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_NICKNAME] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_NICKNAME])) {
|
||||
gen_nickname = cursor.getString(columnIndices[GEN_ID_NICKNAME]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_ADDRESS] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_ADDRESS])) {
|
||||
gen_address = cursor.getString(columnIndices[GEN_ID_ADDRESS]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_PORT] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_PORT])) {
|
||||
gen_port = (int)cursor.getInt(columnIndices[GEN_ID_PORT]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_PASSWORD] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_PASSWORD])) {
|
||||
gen_password = cursor.getString(columnIndices[GEN_ID_PASSWORD]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_COLORMODEL] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_COLORMODEL])) {
|
||||
gen_colorModel = cursor.getString(columnIndices[GEN_ID_COLORMODEL]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_FORCEFULL] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_FORCEFULL])) {
|
||||
gen_forceFull = cursor.getLong(columnIndices[GEN_ID_FORCEFULL]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_REPEATERID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_REPEATERID])) {
|
||||
gen_repeaterId = cursor.getString(columnIndices[GEN_ID_REPEATERID]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_INPUTMODE] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_INPUTMODE])) {
|
||||
gen_inputMode = cursor.getString(columnIndices[GEN_ID_INPUTMODE]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_SCALEMODE] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_SCALEMODE])) {
|
||||
gen_SCALEMODE = cursor.getString(columnIndices[GEN_ID_SCALEMODE]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_USELOCALCURSOR] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_USELOCALCURSOR])) {
|
||||
gen_useLocalCursor = (cursor.getInt(columnIndices[GEN_ID_USELOCALCURSOR]) != 0);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_KEEPPASSWORD] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_KEEPPASSWORD])) {
|
||||
gen_keepPassword = (cursor.getInt(columnIndices[GEN_ID_KEEPPASSWORD]) != 0);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_FOLLOWMOUSE] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_FOLLOWMOUSE])) {
|
||||
gen_followMouse = (cursor.getInt(columnIndices[GEN_ID_FOLLOWMOUSE]) != 0);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_USEREPEATER] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_USEREPEATER])) {
|
||||
gen_useRepeater = (cursor.getInt(columnIndices[GEN_ID_USEREPEATER]) != 0);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_METALISTID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_METALISTID])) {
|
||||
gen_metaListId = cursor.getLong(columnIndices[GEN_ID_METALISTID]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_LAST_META_KEY_ID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_LAST_META_KEY_ID])) {
|
||||
gen_LAST_META_KEY_ID = cursor.getLong(columnIndices[GEN_ID_LAST_META_KEY_ID]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_FOLLOWPAN] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_FOLLOWPAN])) {
|
||||
gen_followPan = (cursor.getInt(columnIndices[GEN_ID_FOLLOWPAN]) != 0);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_USERNAME] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_USERNAME])) {
|
||||
gen_userName = cursor.getString(columnIndices[GEN_ID_USERNAME]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_SECURECONNECTIONTYPE] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_SECURECONNECTIONTYPE])) {
|
||||
gen_secureConnectionType = cursor.getString(columnIndices[GEN_ID_SECURECONNECTIONTYPE]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_SHOWZOOMBUTTONS] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_SHOWZOOMBUTTONS])) {
|
||||
gen_showZoomButtons = (cursor.getInt(columnIndices[GEN_ID_SHOWZOOMBUTTONS]) != 0);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_DOUBLE_TAP_ACTION] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_DOUBLE_TAP_ACTION])) {
|
||||
gen_DOUBLE_TAP_ACTION = cursor.getString(columnIndices[GEN_ID_DOUBLE_TAP_ACTION]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate one instance from a ContentValues
|
||||
*/
|
||||
public void Gen_populate(android.content.ContentValues values) {
|
||||
gen__Id = values.getAsLong(GEN_FIELD__ID);
|
||||
gen_nickname = values.getAsString(GEN_FIELD_NICKNAME);
|
||||
gen_address = values.getAsString(GEN_FIELD_ADDRESS);
|
||||
gen_port = (int)values.getAsInteger(GEN_FIELD_PORT);
|
||||
gen_password = values.getAsString(GEN_FIELD_PASSWORD);
|
||||
gen_colorModel = values.getAsString(GEN_FIELD_COLORMODEL);
|
||||
gen_forceFull = values.getAsLong(GEN_FIELD_FORCEFULL);
|
||||
gen_repeaterId = values.getAsString(GEN_FIELD_REPEATERID);
|
||||
gen_inputMode = values.getAsString(GEN_FIELD_INPUTMODE);
|
||||
gen_SCALEMODE = values.getAsString(GEN_FIELD_SCALEMODE);
|
||||
gen_useLocalCursor = (values.getAsInteger(GEN_FIELD_USELOCALCURSOR) != 0);
|
||||
gen_keepPassword = (values.getAsInteger(GEN_FIELD_KEEPPASSWORD) != 0);
|
||||
gen_followMouse = (values.getAsInteger(GEN_FIELD_FOLLOWMOUSE) != 0);
|
||||
gen_useRepeater = (values.getAsInteger(GEN_FIELD_USEREPEATER) != 0);
|
||||
gen_metaListId = values.getAsLong(GEN_FIELD_METALISTID);
|
||||
gen_LAST_META_KEY_ID = values.getAsLong(GEN_FIELD_LAST_META_KEY_ID);
|
||||
gen_followPan = (values.getAsInteger(GEN_FIELD_FOLLOWPAN) != 0);
|
||||
gen_userName = values.getAsString(GEN_FIELD_USERNAME);
|
||||
gen_secureConnectionType = values.getAsString(GEN_FIELD_SECURECONNECTIONTYPE);
|
||||
gen_showZoomButtons = (values.getAsInteger(GEN_FIELD_SHOWZOOMBUTTONS) != 0);
|
||||
gen_DOUBLE_TAP_ACTION = values.getAsString(GEN_FIELD_DOUBLE_TAP_ACTION);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.antlersoft.android.bc.BCFactory;
|
||||
import com.antlersoft.android.bc.IBCScaleGestureDetector;
|
||||
import com.antlersoft.android.bc.OnScaleGestureListener;
|
||||
|
||||
/**
|
||||
* An AbstractInputHandler that uses GestureDetector to detect standard gestures in touch events
|
||||
*
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
abstract class AbstractGestureInputHandler extends GestureDetector.SimpleOnGestureListener implements AbstractInputHandler, OnScaleGestureListener {
|
||||
protected GestureDetector gestures;
|
||||
protected IBCScaleGestureDetector scaleGestures;
|
||||
private VncCanvasActivity activity;
|
||||
|
||||
float xInitialFocus;
|
||||
float yInitialFocus;
|
||||
boolean inScaling;
|
||||
|
||||
private static final String TAG = "AbstractGestureInputHandler";
|
||||
|
||||
AbstractGestureInputHandler(VncCanvasActivity c)
|
||||
{
|
||||
activity = c;
|
||||
gestures=BCFactory.getInstance().getBCGestureDetector().createGestureDetector(c, this);
|
||||
gestures.setOnDoubleTapListener(this);
|
||||
scaleGestures=BCFactory.getInstance().getScaleGestureDetector(c, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent evt) {
|
||||
scaleGestures.onTouchEvent(evt);
|
||||
return gestures.onTouchEvent(evt);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.OnScaleGestureListener#onScale(com.antlersoft.android.bc.IBCScaleGestureDetector)
|
||||
*/
|
||||
@Override
|
||||
public boolean onScale(IBCScaleGestureDetector detector) {
|
||||
boolean consumed = true;
|
||||
//if (detector.)
|
||||
//Log.i(TAG,"Focus("+detector.getFocusX()+","+detector.getFocusY()+") scaleFactor = "+detector.getScaleFactor());
|
||||
// Calculate focus shift
|
||||
float fx = detector.getFocusX();
|
||||
float fy = detector.getFocusY();
|
||||
double xfs = fx - xInitialFocus;
|
||||
double yfs = fy - yInitialFocus;
|
||||
double fs = Math.sqrt(xfs * xfs + yfs * yfs);
|
||||
if (Math.abs(1.0 - detector.getScaleFactor())<0.02)
|
||||
consumed = false;
|
||||
if (fs * 2< Math.abs(detector.getCurrentSpan() - detector.getPreviousSpan()))
|
||||
{
|
||||
inScaling = true;
|
||||
if (consumed)
|
||||
{
|
||||
//Log.i(TAG,"Adjust scaling "+detector.getScaleFactor());
|
||||
if (activity.vncCanvas != null && activity.vncCanvas.scaling != null)
|
||||
activity.vncCanvas.scaling.adjust(activity, detector.getScaleFactor(), fx, fy);
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.OnScaleGestureListener#onScaleBegin(com.antlersoft.android.bc.IBCScaleGestureDetector)
|
||||
*/
|
||||
@Override
|
||||
public boolean onScaleBegin(IBCScaleGestureDetector detector) {
|
||||
xInitialFocus = detector.getFocusX();
|
||||
yInitialFocus = detector.getFocusY();
|
||||
inScaling = false;
|
||||
//Log.i(TAG,"scale begin ("+xInitialFocus+","+yInitialFocus+")");
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.OnScaleGestureListener#onScaleEnd(com.antlersoft.android.bc.IBCScaleGestureDetector)
|
||||
*/
|
||||
@Override
|
||||
public void onScaleEnd(IBCScaleGestureDetector detector) {
|
||||
//Log.i(TAG,"scale end");
|
||||
inScaling = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* The VncCanvasActivity has several different ways of handling input from the touchscreen,
|
||||
* keyboard, buttons and trackball. These will be represented by different implementations
|
||||
* of this interface. Putting the different modes in different classes
|
||||
* will keep the logic clean. The relevant Activity callbacks in VncCanvasActivity
|
||||
* are forwarded to methods in AbstractInputHandler.
|
||||
* <p>
|
||||
* It is expected that the implementations will be contained within
|
||||
* VncCanvasActivity, so they can do things like super.VncCanvasActivity.onXXX to invoke
|
||||
* default behavior.
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
interface AbstractInputHandler {
|
||||
/**
|
||||
* Note: Menu key code is handled before this is called
|
||||
* @see android.app.Activity#onKeyDown(int keyCode, KeyEvent evt)
|
||||
*/
|
||||
boolean onKeyDown(int keyCode, KeyEvent evt);
|
||||
/**
|
||||
* Note: Menu key code is handled before this is called
|
||||
* @see android.app.Activity#onKeyUp(int keyCode, KeyEvent evt)
|
||||
*/
|
||||
boolean onKeyUp(int keyCode, KeyEvent evt);
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Activity#onTrackballEvent(android.view.MotionEvent)
|
||||
*/
|
||||
boolean onTrackballEvent( MotionEvent evt);
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Activity#onTrackballEvent(android.view.MotionEvent)
|
||||
*/
|
||||
boolean onTouchEvent( MotionEvent evt);
|
||||
|
||||
/**
|
||||
* Return a user-friendly description for this mode; it will be displayed in a toaster
|
||||
* when changing modes.
|
||||
* @return
|
||||
*/
|
||||
CharSequence getHandlerDescription();
|
||||
|
||||
/**
|
||||
* Return an internal name for this handler; this name will be stable across language
|
||||
* and version changes
|
||||
*/
|
||||
String getName();
|
||||
}
|
||||
149
app/src/main/java/android/androidVNC/AbstractMetaKeyBean.java
Normal file
@@ -0,0 +1,149 @@
|
||||
// This class was generated from android.androidVNC.IMetaKey by a tool
|
||||
// Do not edit this file directly! PLX THX
|
||||
package android.androidVNC;
|
||||
|
||||
public abstract class AbstractMetaKeyBean extends com.antlersoft.android.dbimpl.IdImplementationBase implements IMetaKey {
|
||||
|
||||
public static final String GEN_TABLE_NAME = "META_KEY";
|
||||
public static final int GEN_COUNT = 8;
|
||||
|
||||
// Field constants
|
||||
public static final String GEN_FIELD__ID = "_id";
|
||||
public static final int GEN_ID__ID = 0;
|
||||
public static final String GEN_FIELD_METALISTID = "METALISTID";
|
||||
public static final int GEN_ID_METALISTID = 1;
|
||||
public static final String GEN_FIELD_KEYDESC = "KEYDESC";
|
||||
public static final int GEN_ID_KEYDESC = 2;
|
||||
public static final String GEN_FIELD_METAFLAGS = "METAFLAGS";
|
||||
public static final int GEN_ID_METAFLAGS = 3;
|
||||
public static final String GEN_FIELD_MOUSECLICK = "MOUSECLICK";
|
||||
public static final int GEN_ID_MOUSECLICK = 4;
|
||||
public static final String GEN_FIELD_MOUSEBUTTONS = "MOUSEBUTTONS";
|
||||
public static final int GEN_ID_MOUSEBUTTONS = 5;
|
||||
public static final String GEN_FIELD_KEYSYM = "KEYSYM";
|
||||
public static final int GEN_ID_KEYSYM = 6;
|
||||
public static final String GEN_FIELD_SHORTCUT = "SHORTCUT";
|
||||
public static final int GEN_ID_SHORTCUT = 7;
|
||||
|
||||
// SQL Command for creating the table
|
||||
public static String GEN_CREATE = "CREATE TABLE META_KEY (" +
|
||||
"_id INTEGER PRIMARY KEY AUTOINCREMENT," +
|
||||
"METALISTID INTEGER," +
|
||||
"KEYDESC TEXT," +
|
||||
"METAFLAGS INTEGER," +
|
||||
"MOUSECLICK INTEGER," +
|
||||
"MOUSEBUTTONS INTEGER," +
|
||||
"KEYSYM INTEGER," +
|
||||
"SHORTCUT TEXT" +
|
||||
")";
|
||||
|
||||
// Members corresponding to defined fields
|
||||
private long gen__Id;
|
||||
private long gen_metaListId;
|
||||
private java.lang.String gen_keyDesc;
|
||||
private int gen_metaFlags;
|
||||
private boolean gen_mouseClick;
|
||||
private int gen_mouseButtons;
|
||||
private int gen_keySym;
|
||||
private java.lang.String gen_shortcut;
|
||||
|
||||
|
||||
public String Gen_tableName() { return GEN_TABLE_NAME; }
|
||||
|
||||
// Field accessors
|
||||
public long get_Id() { return gen__Id; }
|
||||
public void set_Id(long arg__Id) { gen__Id = arg__Id; }
|
||||
public long getMetaListId() { return gen_metaListId; }
|
||||
public void setMetaListId(long arg_metaListId) { gen_metaListId = arg_metaListId; }
|
||||
public java.lang.String getKeyDesc() { return gen_keyDesc; }
|
||||
public void setKeyDesc(java.lang.String arg_keyDesc) { gen_keyDesc = arg_keyDesc; }
|
||||
public int getMetaFlags() { return gen_metaFlags; }
|
||||
public void setMetaFlags(int arg_metaFlags) { gen_metaFlags = arg_metaFlags; }
|
||||
public boolean isMouseClick() { return gen_mouseClick; }
|
||||
public void setMouseClick(boolean arg_mouseClick) { gen_mouseClick = arg_mouseClick; }
|
||||
public int getMouseButtons() { return gen_mouseButtons; }
|
||||
public void setMouseButtons(int arg_mouseButtons) { gen_mouseButtons = arg_mouseButtons; }
|
||||
public int getKeySym() { return gen_keySym; }
|
||||
public void setKeySym(int arg_keySym) { gen_keySym = arg_keySym; }
|
||||
public java.lang.String getShortcut() { return gen_shortcut; }
|
||||
public void setShortcut(java.lang.String arg_shortcut) { gen_shortcut = arg_shortcut; }
|
||||
|
||||
public android.content.ContentValues Gen_getValues() {
|
||||
android.content.ContentValues values=new android.content.ContentValues();
|
||||
values.put(GEN_FIELD__ID,Long.toString(this.gen__Id));
|
||||
values.put(GEN_FIELD_METALISTID,Long.toString(this.gen_metaListId));
|
||||
values.put(GEN_FIELD_KEYDESC,this.gen_keyDesc);
|
||||
values.put(GEN_FIELD_METAFLAGS,Integer.toString(this.gen_metaFlags));
|
||||
values.put(GEN_FIELD_MOUSECLICK,(this.gen_mouseClick ? "1" : "0"));
|
||||
values.put(GEN_FIELD_MOUSEBUTTONS,Integer.toString(this.gen_mouseButtons));
|
||||
values.put(GEN_FIELD_KEYSYM,Integer.toString(this.gen_keySym));
|
||||
values.put(GEN_FIELD_SHORTCUT,this.gen_shortcut);
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array that gives the column index in the cursor for each field defined
|
||||
* @param cursor Database cursor over some columns, possibly including this table
|
||||
* @return array of column indices; -1 if the column with that id is not in cursor
|
||||
*/
|
||||
public int[] Gen_columnIndices(android.database.Cursor cursor) {
|
||||
int[] result=new int[GEN_COUNT];
|
||||
result[0] = cursor.getColumnIndex(GEN_FIELD__ID);
|
||||
// Make compatible with database generated by older version of plugin with uppercase column name
|
||||
if (result[0] == -1) {
|
||||
result[0] = cursor.getColumnIndex("_ID");
|
||||
}
|
||||
result[1] = cursor.getColumnIndex(GEN_FIELD_METALISTID);
|
||||
result[2] = cursor.getColumnIndex(GEN_FIELD_KEYDESC);
|
||||
result[3] = cursor.getColumnIndex(GEN_FIELD_METAFLAGS);
|
||||
result[4] = cursor.getColumnIndex(GEN_FIELD_MOUSECLICK);
|
||||
result[5] = cursor.getColumnIndex(GEN_FIELD_MOUSEBUTTONS);
|
||||
result[6] = cursor.getColumnIndex(GEN_FIELD_KEYSYM);
|
||||
result[7] = cursor.getColumnIndex(GEN_FIELD_SHORTCUT);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate one instance from a cursor
|
||||
*/
|
||||
public void Gen_populate(android.database.Cursor cursor,int[] columnIndices) {
|
||||
if ( columnIndices[GEN_ID__ID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID__ID])) {
|
||||
gen__Id = cursor.getLong(columnIndices[GEN_ID__ID]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_METALISTID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_METALISTID])) {
|
||||
gen_metaListId = cursor.getLong(columnIndices[GEN_ID_METALISTID]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_KEYDESC] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_KEYDESC])) {
|
||||
gen_keyDesc = cursor.getString(columnIndices[GEN_ID_KEYDESC]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_METAFLAGS] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_METAFLAGS])) {
|
||||
gen_metaFlags = (int)cursor.getInt(columnIndices[GEN_ID_METAFLAGS]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_MOUSECLICK] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_MOUSECLICK])) {
|
||||
gen_mouseClick = (cursor.getInt(columnIndices[GEN_ID_MOUSECLICK]) != 0);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_MOUSEBUTTONS] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_MOUSEBUTTONS])) {
|
||||
gen_mouseButtons = (int)cursor.getInt(columnIndices[GEN_ID_MOUSEBUTTONS]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_KEYSYM] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_KEYSYM])) {
|
||||
gen_keySym = (int)cursor.getInt(columnIndices[GEN_ID_KEYSYM]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_SHORTCUT] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_SHORTCUT])) {
|
||||
gen_shortcut = cursor.getString(columnIndices[GEN_ID_SHORTCUT]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate one instance from a ContentValues
|
||||
*/
|
||||
public void Gen_populate(android.content.ContentValues values) {
|
||||
gen__Id = values.getAsLong(GEN_FIELD__ID);
|
||||
gen_metaListId = values.getAsLong(GEN_FIELD_METALISTID);
|
||||
gen_keyDesc = values.getAsString(GEN_FIELD_KEYDESC);
|
||||
gen_metaFlags = (int)values.getAsInteger(GEN_FIELD_METAFLAGS);
|
||||
gen_mouseClick = (values.getAsInteger(GEN_FIELD_MOUSECLICK) != 0);
|
||||
gen_mouseButtons = (int)values.getAsInteger(GEN_FIELD_MOUSEBUTTONS);
|
||||
gen_keySym = (int)values.getAsInteger(GEN_FIELD_KEYSYM);
|
||||
gen_shortcut = values.getAsString(GEN_FIELD_SHORTCUT);
|
||||
}
|
||||
}
|
||||
129
app/src/main/java/android/androidVNC/AbstractScaling.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.widget.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
* A scaling mode for the VncCanvas; based on ImageView.ScaleType
|
||||
*/
|
||||
abstract class AbstractScaling {
|
||||
private static final int scaleModeIds[] = { R.id.itemFitToScreen, R.id.itemOneToOne, R.id.itemZoomable };
|
||||
|
||||
private static AbstractScaling[] scalings;
|
||||
|
||||
static AbstractScaling getById(int id)
|
||||
{
|
||||
if ( scalings==null)
|
||||
{
|
||||
scalings=new AbstractScaling[scaleModeIds.length];
|
||||
}
|
||||
for ( int i=0; i<scaleModeIds.length; ++i)
|
||||
{
|
||||
if ( scaleModeIds[i]==id)
|
||||
{
|
||||
if ( scalings[i]==null)
|
||||
{
|
||||
switch ( id )
|
||||
{
|
||||
case R.id.itemFitToScreen :
|
||||
scalings[i]=new FitToScreenScaling();
|
||||
break;
|
||||
case R.id.itemOneToOne :
|
||||
scalings[i]=new OneToOneScaling();
|
||||
break;
|
||||
case R.id.itemZoomable :
|
||||
scalings[i]=new ZoomScaling();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return scalings[i];
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown scaling id " + id);
|
||||
}
|
||||
|
||||
float getScale() { return 1; }
|
||||
|
||||
void zoomIn(VncCanvasActivity activity) {}
|
||||
void zoomOut(VncCanvasActivity activity) {}
|
||||
|
||||
static AbstractScaling getByScaleType(ImageView.ScaleType scaleType)
|
||||
{
|
||||
for (int i : scaleModeIds)
|
||||
{
|
||||
AbstractScaling s = getById(i);
|
||||
if (s.scaleType==scaleType)
|
||||
return s;
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported scale type: "+ scaleType.toString());
|
||||
}
|
||||
|
||||
private int id;
|
||||
protected ImageView.ScaleType scaleType;
|
||||
|
||||
protected AbstractScaling(int id, ImageView.ScaleType scaleType)
|
||||
{
|
||||
this.id = id;
|
||||
this.scaleType = scaleType;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Id corresponding to menu item that sets this scale type
|
||||
*/
|
||||
int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the activity's scale type to the scaling
|
||||
* @param activity
|
||||
*/
|
||||
void setScaleTypeForActivity(VncCanvasActivity activity)
|
||||
{
|
||||
activity.zoomer.hide();
|
||||
activity.vncCanvas.scaling = this;
|
||||
activity.vncCanvas.setScaleType(scaleType);
|
||||
activity.getConnection().setScaleMode(scaleType);
|
||||
if (activity.inputHandler == null || ! isValidInputMode(activity.getModeIdFromHandler(activity.inputHandler))) {
|
||||
activity.inputHandler=activity.getInputHandlerById(getDefaultHandlerId());
|
||||
activity.getConnection().setInputMode(activity.inputHandler.getName());
|
||||
}
|
||||
activity.getConnection().Gen_update(activity.database.getWritableDatabase());
|
||||
activity.updateInputMenu();
|
||||
}
|
||||
|
||||
abstract int getDefaultHandlerId();
|
||||
|
||||
/**
|
||||
* True if this scale type allows panning of the image
|
||||
* @return
|
||||
*/
|
||||
abstract boolean isAbleToPan();
|
||||
|
||||
/**
|
||||
* True if the listed input mode is valid for this scaling mode
|
||||
* @param mode Id of the input mode
|
||||
* @return True if the input mode is compatible with the scaling mode
|
||||
*/
|
||||
abstract boolean isValidInputMode(int mode);
|
||||
|
||||
/**
|
||||
* Change the scaling and focus dynamically, as from a detected scale gesture
|
||||
* @param activity Activity containing to canvas to scale
|
||||
* @param scaleFactor Factor by which to adjust scaling
|
||||
* @param fx Focus X of center of scale change
|
||||
* @param fy Focus Y of center of scale change
|
||||
*/
|
||||
void adjust(VncCanvasActivity activity, float scaleFactor, float fx, float fy)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
7
app/src/main/java/android/androidVNC/BitmapImplHint.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package android.androidVNC;
|
||||
|
||||
class BitmapImplHint {
|
||||
static final long AUTO = 0L;
|
||||
static final long FULL = 1L;
|
||||
static final long TILE = 2L;
|
||||
}
|
||||
89
app/src/main/java/android/androidVNC/COLORMODEL.java
Normal file
@@ -0,0 +1,89 @@
|
||||
package android.androidVNC;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public enum COLORMODEL {
|
||||
C24bit, C256, C64, C8, C4, C2;
|
||||
|
||||
public int bpp() {
|
||||
switch (this) {
|
||||
case C24bit:
|
||||
return 4;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public int[] palette() {
|
||||
switch (this) {
|
||||
case C24bit:
|
||||
return null;
|
||||
case C256:
|
||||
return ColorModel256.colors;
|
||||
case C64:
|
||||
return ColorModel64.colors;
|
||||
case C8:
|
||||
return ColorModel8.colors;
|
||||
case C4:
|
||||
return ColorModel64.colors;
|
||||
case C2:
|
||||
return ColorModel8.colors;
|
||||
default:
|
||||
return ColorModel256.colors;
|
||||
}
|
||||
}
|
||||
|
||||
public String nameString()
|
||||
{
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
public void setPixelFormat(RfbProto rfb) throws IOException {
|
||||
switch (this) {
|
||||
case C24bit:
|
||||
// 24-bit color
|
||||
rfb.writeSetPixelFormat(32, 24, false, true, 255, 255, 255, 16, 8, 0, false);
|
||||
break;
|
||||
case C256:
|
||||
rfb.writeSetPixelFormat(8, 8, false, true, 7, 7, 3, 0, 3, 6, false);
|
||||
break;
|
||||
case C64:
|
||||
rfb.writeSetPixelFormat(8, 6, false, true, 3, 3, 3, 4, 2, 0, false);
|
||||
break;
|
||||
case C8:
|
||||
rfb.writeSetPixelFormat(8, 3, false, true, 1, 1, 1, 2, 1, 0, false);
|
||||
break;
|
||||
case C4:
|
||||
// Greyscale
|
||||
rfb.writeSetPixelFormat(8, 6, false, true, 3, 3, 3, 4, 2, 0, true);
|
||||
break;
|
||||
case C2:
|
||||
// B&W
|
||||
rfb.writeSetPixelFormat(8, 3, false, true, 1, 1, 1, 2, 1, 0, true);
|
||||
break;
|
||||
default:
|
||||
// Default is 256 colors
|
||||
rfb.writeSetPixelFormat(8, 8, false, true, 7, 7, 3, 0, 3, 6, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
switch (this) {
|
||||
case C24bit:
|
||||
return "24-bit color (4 bpp)";
|
||||
case C256:
|
||||
return "256 colors (1 bpp)";
|
||||
case C64:
|
||||
return "64 colors (1 bpp)";
|
||||
case C8:
|
||||
return "8 colors (1 bpp)";
|
||||
case C4:
|
||||
return "Greyscale (1 bpp)";
|
||||
case C2:
|
||||
return "Black & White (1 bpp)";
|
||||
default:
|
||||
return "256 colors (1 bpp)";
|
||||
}
|
||||
}
|
||||
}
|
||||
88
app/src/main/java/android/androidVNC/CapabilityInfo.java
Normal file
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// Copyright (C) 2003 Constantin Kaplinsky. All Rights Reserved.
|
||||
//
|
||||
// This 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 software 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 software; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
//
|
||||
|
||||
//
|
||||
// CapabilityInfo.java - A class to hold information about a
|
||||
// particular capability as used in the RFB protocol 3.130.
|
||||
//
|
||||
package android.androidVNC;
|
||||
|
||||
class CapabilityInfo {
|
||||
|
||||
// Public methods
|
||||
|
||||
public CapabilityInfo(int code,
|
||||
String vendorSignature,
|
||||
String nameSignature,
|
||||
String description) {
|
||||
this.code = code;
|
||||
this.vendorSignature = vendorSignature;
|
||||
this.nameSignature = nameSignature;
|
||||
this.description = description;
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
public CapabilityInfo(int code,
|
||||
byte[] vendorSignature,
|
||||
byte[] nameSignature) {
|
||||
this.code = code;
|
||||
this.vendorSignature = new String(vendorSignature);
|
||||
this.nameSignature = new String(nameSignature);
|
||||
this.description = null;
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
public boolean equals(CapabilityInfo other) {
|
||||
return (other != null && this.code == other.code &&
|
||||
this.vendorSignature.equals(other.vendorSignature) &&
|
||||
this.nameSignature.equals(other.nameSignature));
|
||||
}
|
||||
|
||||
public boolean enableIfEquals(CapabilityInfo other) {
|
||||
if (this.equals(other))
|
||||
enable();
|
||||
|
||||
return isEnabled();
|
||||
}
|
||||
|
||||
// Protected data
|
||||
|
||||
protected int code;
|
||||
protected String vendorSignature;
|
||||
protected String nameSignature;
|
||||
|
||||
protected String description;
|
||||
protected boolean enabled;
|
||||
}
|
||||
104
app/src/main/java/android/androidVNC/CapsContainer.java
Normal file
@@ -0,0 +1,104 @@
|
||||
//
|
||||
// Copyright (C) 2003 Constantin Kaplinsky. All Rights Reserved.
|
||||
//
|
||||
// This 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 software 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 software; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
//
|
||||
|
||||
//
|
||||
// CapsContainer.java - A container of capabilities as used in the RFB
|
||||
// protocol 3.130
|
||||
//
|
||||
package android.androidVNC;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.Hashtable;
|
||||
|
||||
class CapsContainer {
|
||||
|
||||
// Public methods
|
||||
|
||||
public CapsContainer() {
|
||||
infoMap = new Hashtable<Integer, CapabilityInfo>(64, (float)0.25);
|
||||
orderedList = new Vector<Integer>(32, 8);
|
||||
}
|
||||
|
||||
public void add(CapabilityInfo capinfo) {
|
||||
Integer key = new Integer(capinfo.getCode());
|
||||
infoMap.put(key, capinfo);
|
||||
}
|
||||
|
||||
public void add(int code, String vendor, String name, String desc) {
|
||||
Integer key = new Integer(code);
|
||||
infoMap.put(key, new CapabilityInfo(code, vendor, name, desc));
|
||||
}
|
||||
|
||||
public boolean isKnown(int code) {
|
||||
return infoMap.containsKey(new Integer(code));
|
||||
}
|
||||
|
||||
public CapabilityInfo getInfo(int code) {
|
||||
return (CapabilityInfo)infoMap.get(new Integer(code));
|
||||
}
|
||||
|
||||
public String getDescription(int code) {
|
||||
CapabilityInfo capinfo = (CapabilityInfo)infoMap.get(new Integer(code));
|
||||
if (capinfo == null)
|
||||
return null;
|
||||
|
||||
return capinfo.getDescription();
|
||||
}
|
||||
|
||||
public boolean enable(CapabilityInfo other) {
|
||||
Integer key = new Integer(other.getCode());
|
||||
CapabilityInfo capinfo = (CapabilityInfo)infoMap.get(key);
|
||||
if (capinfo == null)
|
||||
return false;
|
||||
|
||||
boolean enabled = capinfo.enableIfEquals(other);
|
||||
if (enabled)
|
||||
orderedList.addElement(key);
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled(int code) {
|
||||
CapabilityInfo capinfo = (CapabilityInfo)infoMap.get(new Integer(code));
|
||||
if (capinfo == null)
|
||||
return false;
|
||||
|
||||
return capinfo.isEnabled();
|
||||
}
|
||||
|
||||
public int numEnabled() {
|
||||
return orderedList.size();
|
||||
}
|
||||
|
||||
public int getByOrder(int idx) {
|
||||
int code;
|
||||
try {
|
||||
code = ((Integer)orderedList.elementAt(idx)).intValue();
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
code = 0;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
// Protected data
|
||||
|
||||
protected Hashtable<Integer, CapabilityInfo> infoMap;
|
||||
protected Vector<Integer> orderedList;
|
||||
}
|
||||
|
||||
266
app/src/main/java/android/androidVNC/ColorModel256.java
Normal file
@@ -0,0 +1,266 @@
|
||||
package android.androidVNC;
|
||||
|
||||
public class ColorModel256 {
|
||||
|
||||
public final static int [] colors;
|
||||
|
||||
static {
|
||||
colors = new int[256];
|
||||
colors[0]=0xff000000;
|
||||
colors[1]=0xff240000;
|
||||
colors[2]=0xff490000;
|
||||
colors[3]=0xff6d0000;
|
||||
colors[4]=0xff920000;
|
||||
colors[5]=0xffb60000;
|
||||
colors[6]=0xffdb0000;
|
||||
colors[7]=0xffff0000;
|
||||
colors[8]=0xff002400;
|
||||
colors[9]=0xff242400;
|
||||
colors[10]=0xff492400;
|
||||
colors[11]=0xff6d2400;
|
||||
colors[12]=0xff922400;
|
||||
colors[13]=0xffb62400;
|
||||
colors[14]=0xffdb2400;
|
||||
colors[15]=0xffff2400;
|
||||
colors[16]=0xff004900;
|
||||
colors[17]=0xff244900;
|
||||
colors[18]=0xff494900;
|
||||
colors[19]=0xff6d4900;
|
||||
colors[20]=0xff924900;
|
||||
colors[21]=0xffb64900;
|
||||
colors[22]=0xffdb4900;
|
||||
colors[23]=0xffff4900;
|
||||
colors[24]=0xff006d00;
|
||||
colors[25]=0xff246d00;
|
||||
colors[26]=0xff496d00;
|
||||
colors[27]=0xff6d6d00;
|
||||
colors[28]=0xff926d00;
|
||||
colors[29]=0xffb66d00;
|
||||
colors[30]=0xffdb6d00;
|
||||
colors[31]=0xffff6d00;
|
||||
colors[32]=0xff009200;
|
||||
colors[33]=0xff249200;
|
||||
colors[34]=0xff499200;
|
||||
colors[35]=0xff6d9200;
|
||||
colors[36]=0xff929200;
|
||||
colors[37]=0xffb69200;
|
||||
colors[38]=0xffdb9200;
|
||||
colors[39]=0xffff9200;
|
||||
colors[40]=0xff00b600;
|
||||
colors[41]=0xff24b600;
|
||||
colors[42]=0xff49b600;
|
||||
colors[43]=0xff6db600;
|
||||
colors[44]=0xff92b600;
|
||||
colors[45]=0xffb6b600;
|
||||
colors[46]=0xffdbb600;
|
||||
colors[47]=0xffffb600;
|
||||
colors[48]=0xff00db00;
|
||||
colors[49]=0xff24db00;
|
||||
colors[50]=0xff49db00;
|
||||
colors[51]=0xff6ddb00;
|
||||
colors[52]=0xff92db00;
|
||||
colors[53]=0xffb6db00;
|
||||
colors[54]=0xffdbdb00;
|
||||
colors[55]=0xffffdb00;
|
||||
colors[56]=0xff00ff00;
|
||||
colors[57]=0xff24ff00;
|
||||
colors[58]=0xff49ff00;
|
||||
colors[59]=0xff6dff00;
|
||||
colors[60]=0xff92ff00;
|
||||
colors[61]=0xffb6ff00;
|
||||
colors[62]=0xffdbff00;
|
||||
colors[63]=0xffffff00;
|
||||
colors[64]=0xff000055;
|
||||
colors[65]=0xff240055;
|
||||
colors[66]=0xff490055;
|
||||
colors[67]=0xff6d0055;
|
||||
colors[68]=0xff920055;
|
||||
colors[69]=0xffb60055;
|
||||
colors[70]=0xffdb0055;
|
||||
colors[71]=0xffff0055;
|
||||
colors[72]=0xff002455;
|
||||
colors[73]=0xff242455;
|
||||
colors[74]=0xff492455;
|
||||
colors[75]=0xff6d2455;
|
||||
colors[76]=0xff922455;
|
||||
colors[77]=0xffb62455;
|
||||
colors[78]=0xffdb2455;
|
||||
colors[79]=0xffff2455;
|
||||
colors[80]=0xff004955;
|
||||
colors[81]=0xff244955;
|
||||
colors[82]=0xff494955;
|
||||
colors[83]=0xff6d4955;
|
||||
colors[84]=0xff924955;
|
||||
colors[85]=0xffb64955;
|
||||
colors[86]=0xffdb4955;
|
||||
colors[87]=0xffff4955;
|
||||
colors[88]=0xff006d55;
|
||||
colors[89]=0xff246d55;
|
||||
colors[90]=0xff496d55;
|
||||
colors[91]=0xff6d6d55;
|
||||
colors[92]=0xff926d55;
|
||||
colors[93]=0xffb66d55;
|
||||
colors[94]=0xffdb6d55;
|
||||
colors[95]=0xffff6d55;
|
||||
colors[96]=0xff009255;
|
||||
colors[97]=0xff249255;
|
||||
colors[98]=0xff499255;
|
||||
colors[99]=0xff6d9255;
|
||||
colors[100]=0xff929255;
|
||||
colors[101]=0xffb69255;
|
||||
colors[102]=0xffdb9255;
|
||||
colors[103]=0xffff9255;
|
||||
colors[104]=0xff00b655;
|
||||
colors[105]=0xff24b655;
|
||||
colors[106]=0xff49b655;
|
||||
colors[107]=0xff6db655;
|
||||
colors[108]=0xff92b655;
|
||||
colors[109]=0xffb6b655;
|
||||
colors[110]=0xffdbb655;
|
||||
colors[111]=0xffffb655;
|
||||
colors[112]=0xff00db55;
|
||||
colors[113]=0xff24db55;
|
||||
colors[114]=0xff49db55;
|
||||
colors[115]=0xff6ddb55;
|
||||
colors[116]=0xff92db55;
|
||||
colors[117]=0xffb6db55;
|
||||
colors[118]=0xffdbdb55;
|
||||
colors[119]=0xffffdb55;
|
||||
colors[120]=0xff00ff55;
|
||||
colors[121]=0xff24ff55;
|
||||
colors[122]=0xff49ff55;
|
||||
colors[123]=0xff6dff55;
|
||||
colors[124]=0xff92ff55;
|
||||
colors[125]=0xffb6ff55;
|
||||
colors[126]=0xffdbff55;
|
||||
colors[127]=0xffffff55;
|
||||
colors[128]=0xff0000aa;
|
||||
colors[129]=0xff2400aa;
|
||||
colors[130]=0xff4900aa;
|
||||
colors[131]=0xff6d00aa;
|
||||
colors[132]=0xff9200aa;
|
||||
colors[133]=0xffb600aa;
|
||||
colors[134]=0xffdb00aa;
|
||||
colors[135]=0xffff00aa;
|
||||
colors[136]=0xff0024aa;
|
||||
colors[137]=0xff2424aa;
|
||||
colors[138]=0xff4924aa;
|
||||
colors[139]=0xff6d24aa;
|
||||
colors[140]=0xff9224aa;
|
||||
colors[141]=0xffb624aa;
|
||||
colors[142]=0xffdb24aa;
|
||||
colors[143]=0xffff24aa;
|
||||
colors[144]=0xff0049aa;
|
||||
colors[145]=0xff2449aa;
|
||||
colors[146]=0xff4949aa;
|
||||
colors[147]=0xff6d49aa;
|
||||
colors[148]=0xff9249aa;
|
||||
colors[149]=0xffb649aa;
|
||||
colors[150]=0xffdb49aa;
|
||||
colors[151]=0xffff49aa;
|
||||
colors[152]=0xff006daa;
|
||||
colors[153]=0xff246daa;
|
||||
colors[154]=0xff496daa;
|
||||
colors[155]=0xff6d6daa;
|
||||
colors[156]=0xff926daa;
|
||||
colors[157]=0xffb66daa;
|
||||
colors[158]=0xffdb6daa;
|
||||
colors[159]=0xffff6daa;
|
||||
colors[160]=0xff0092aa;
|
||||
colors[161]=0xff2492aa;
|
||||
colors[162]=0xff4992aa;
|
||||
colors[163]=0xff6d92aa;
|
||||
colors[164]=0xff9292aa;
|
||||
colors[165]=0xffb692aa;
|
||||
colors[166]=0xffdb92aa;
|
||||
colors[167]=0xffff92aa;
|
||||
colors[168]=0xff00b6aa;
|
||||
colors[169]=0xff24b6aa;
|
||||
colors[170]=0xff49b6aa;
|
||||
colors[171]=0xff6db6aa;
|
||||
colors[172]=0xff92b6aa;
|
||||
colors[173]=0xffb6b6aa;
|
||||
colors[174]=0xffdbb6aa;
|
||||
colors[175]=0xffffb6aa;
|
||||
colors[176]=0xff00dbaa;
|
||||
colors[177]=0xff24dbaa;
|
||||
colors[178]=0xff49dbaa;
|
||||
colors[179]=0xff6ddbaa;
|
||||
colors[180]=0xff92dbaa;
|
||||
colors[181]=0xffb6dbaa;
|
||||
colors[182]=0xffdbdbaa;
|
||||
colors[183]=0xffffdbaa;
|
||||
colors[184]=0xff00ffaa;
|
||||
colors[185]=0xff24ffaa;
|
||||
colors[186]=0xff49ffaa;
|
||||
colors[187]=0xff6dffaa;
|
||||
colors[188]=0xff92ffaa;
|
||||
colors[189]=0xffb6ffaa;
|
||||
colors[190]=0xffdbffaa;
|
||||
colors[191]=0xffffffaa;
|
||||
colors[192]=0xff0000ff;
|
||||
colors[193]=0xff2400ff;
|
||||
colors[194]=0xff4900ff;
|
||||
colors[195]=0xff6d00ff;
|
||||
colors[196]=0xff9200ff;
|
||||
colors[197]=0xffb600ff;
|
||||
colors[198]=0xffdb00ff;
|
||||
colors[199]=0xffff00ff;
|
||||
colors[200]=0xff0024ff;
|
||||
colors[201]=0xff2424ff;
|
||||
colors[202]=0xff4924ff;
|
||||
colors[203]=0xff6d24ff;
|
||||
colors[204]=0xff9224ff;
|
||||
colors[205]=0xffb624ff;
|
||||
colors[206]=0xffdb24ff;
|
||||
colors[207]=0xffff24ff;
|
||||
colors[208]=0xff0049ff;
|
||||
colors[209]=0xff2449ff;
|
||||
colors[210]=0xff4949ff;
|
||||
colors[211]=0xff6d49ff;
|
||||
colors[212]=0xff9249ff;
|
||||
colors[213]=0xffb649ff;
|
||||
colors[214]=0xffdb49ff;
|
||||
colors[215]=0xffff49ff;
|
||||
colors[216]=0xff006dff;
|
||||
colors[217]=0xff246dff;
|
||||
colors[218]=0xff496dff;
|
||||
colors[219]=0xff6d6dff;
|
||||
colors[220]=0xff926dff;
|
||||
colors[221]=0xffb66dff;
|
||||
colors[222]=0xffdb6dff;
|
||||
colors[223]=0xffff6dff;
|
||||
colors[224]=0xff0092ff;
|
||||
colors[225]=0xff2492ff;
|
||||
colors[226]=0xff4992ff;
|
||||
colors[227]=0xff6d92ff;
|
||||
colors[228]=0xff9292ff;
|
||||
colors[229]=0xffb692ff;
|
||||
colors[230]=0xffdb92ff;
|
||||
colors[231]=0xffff92ff;
|
||||
colors[232]=0xff00b6ff;
|
||||
colors[233]=0xff24b6ff;
|
||||
colors[234]=0xff49b6ff;
|
||||
colors[235]=0xff6db6ff;
|
||||
colors[236]=0xff92b6ff;
|
||||
colors[237]=0xffb6b6ff;
|
||||
colors[238]=0xffdbb6ff;
|
||||
colors[239]=0xffffb6ff;
|
||||
colors[240]=0xff00dbff;
|
||||
colors[241]=0xff24dbff;
|
||||
colors[242]=0xff49dbff;
|
||||
colors[243]=0xff6ddbff;
|
||||
colors[244]=0xff92dbff;
|
||||
colors[245]=0xffb6dbff;
|
||||
colors[246]=0xffdbdbff;
|
||||
colors[247]=0xffffdbff;
|
||||
colors[248]=0xff00ffff;
|
||||
colors[249]=0xff24ffff;
|
||||
colors[250]=0xff49ffff;
|
||||
colors[251]=0xff6dffff;
|
||||
colors[252]=0xff92ffff;
|
||||
colors[253]=0xffb6ffff;
|
||||
colors[254]=0xffdbffff;
|
||||
colors[255]=0xffffffff;
|
||||
}
|
||||
}
|
||||
267
app/src/main/java/android/androidVNC/ColorModel64.java
Normal file
@@ -0,0 +1,267 @@
|
||||
package android.androidVNC;
|
||||
|
||||
public class ColorModel64 {
|
||||
|
||||
public final static int [] colors;
|
||||
|
||||
static {
|
||||
colors = new int[256];
|
||||
colors[0]=0xff000000;
|
||||
colors[1]=0xff000055;
|
||||
colors[2]=0xff0000aa;
|
||||
colors[3]=0xff0000ff;
|
||||
colors[4]=0xff005500;
|
||||
colors[5]=0xff005555;
|
||||
colors[6]=0xff0055aa;
|
||||
colors[7]=0xff0055ff;
|
||||
colors[8]=0xff00aa00;
|
||||
colors[9]=0xff00aa55;
|
||||
colors[10]=0xff00aaaa;
|
||||
colors[11]=0xff00aaff;
|
||||
colors[12]=0xff00ff00;
|
||||
colors[13]=0xff00ff55;
|
||||
colors[14]=0xff00ffaa;
|
||||
colors[15]=0xff00ffff;
|
||||
colors[16]=0xff550000;
|
||||
colors[17]=0xff550055;
|
||||
colors[18]=0xff5500aa;
|
||||
colors[19]=0xff5500ff;
|
||||
colors[20]=0xff555500;
|
||||
colors[21]=0xff555555;
|
||||
colors[22]=0xff5555aa;
|
||||
colors[23]=0xff5555ff;
|
||||
colors[24]=0xff55aa00;
|
||||
colors[25]=0xff55aa55;
|
||||
colors[26]=0xff55aaaa;
|
||||
colors[27]=0xff55aaff;
|
||||
colors[28]=0xff55ff00;
|
||||
colors[29]=0xff55ff55;
|
||||
colors[30]=0xff55ffaa;
|
||||
colors[31]=0xff55ffff;
|
||||
colors[32]=0xffaa0000;
|
||||
colors[33]=0xffaa0055;
|
||||
colors[34]=0xffaa00aa;
|
||||
colors[35]=0xffaa00ff;
|
||||
colors[36]=0xffaa5500;
|
||||
colors[37]=0xffaa5555;
|
||||
colors[38]=0xffaa55aa;
|
||||
colors[39]=0xffaa55ff;
|
||||
colors[40]=0xffaaaa00;
|
||||
colors[41]=0xffaaaa55;
|
||||
colors[42]=0xffaaaaaa;
|
||||
colors[43]=0xffaaaaff;
|
||||
colors[44]=0xffaaff00;
|
||||
colors[45]=0xffaaff55;
|
||||
colors[46]=0xffaaffaa;
|
||||
colors[47]=0xffaaffff;
|
||||
colors[48]=0xffff0000;
|
||||
colors[49]=0xffff0055;
|
||||
colors[50]=0xffff00aa;
|
||||
colors[51]=0xffff00ff;
|
||||
colors[52]=0xffff5500;
|
||||
colors[53]=0xffff5555;
|
||||
colors[54]=0xffff55aa;
|
||||
colors[55]=0xffff55ff;
|
||||
colors[56]=0xffffaa00;
|
||||
colors[57]=0xffffaa55;
|
||||
colors[58]=0xffffaaaa;
|
||||
colors[59]=0xffffaaff;
|
||||
colors[60]=0xffffff00;
|
||||
colors[61]=0xffffff55;
|
||||
colors[62]=0xffffffaa;
|
||||
colors[63]=0xffffffff;
|
||||
colors[64]=0xff000000;
|
||||
colors[65]=0xff000055;
|
||||
colors[66]=0xff0000aa;
|
||||
colors[67]=0xff0000ff;
|
||||
colors[68]=0xff005500;
|
||||
colors[69]=0xff005555;
|
||||
colors[70]=0xff0055aa;
|
||||
colors[71]=0xff0055ff;
|
||||
colors[72]=0xff00aa00;
|
||||
colors[73]=0xff00aa55;
|
||||
colors[74]=0xff00aaaa;
|
||||
colors[75]=0xff00aaff;
|
||||
colors[76]=0xff00ff00;
|
||||
colors[77]=0xff00ff55;
|
||||
colors[78]=0xff00ffaa;
|
||||
colors[79]=0xff00ffff;
|
||||
colors[80]=0xff550000;
|
||||
colors[81]=0xff550055;
|
||||
colors[82]=0xff5500aa;
|
||||
colors[83]=0xff5500ff;
|
||||
colors[84]=0xff555500;
|
||||
colors[85]=0xff555555;
|
||||
colors[86]=0xff5555aa;
|
||||
colors[87]=0xff5555ff;
|
||||
colors[88]=0xff55aa00;
|
||||
colors[89]=0xff55aa55;
|
||||
colors[90]=0xff55aaaa;
|
||||
colors[91]=0xff55aaff;
|
||||
colors[92]=0xff55ff00;
|
||||
colors[93]=0xff55ff55;
|
||||
colors[94]=0xff55ffaa;
|
||||
colors[95]=0xff55ffff;
|
||||
colors[96]=0xffaa0000;
|
||||
colors[97]=0xffaa0055;
|
||||
colors[98]=0xffaa00aa;
|
||||
colors[99]=0xffaa00ff;
|
||||
colors[100]=0xffaa5500;
|
||||
colors[101]=0xffaa5555;
|
||||
colors[102]=0xffaa55aa;
|
||||
colors[103]=0xffaa55ff;
|
||||
colors[104]=0xffaaaa00;
|
||||
colors[105]=0xffaaaa55;
|
||||
colors[106]=0xffaaaaaa;
|
||||
colors[107]=0xffaaaaff;
|
||||
colors[108]=0xffaaff00;
|
||||
colors[109]=0xffaaff55;
|
||||
colors[110]=0xffaaffaa;
|
||||
colors[111]=0xffaaffff;
|
||||
colors[112]=0xffff0000;
|
||||
colors[113]=0xffff0055;
|
||||
colors[114]=0xffff00aa;
|
||||
colors[115]=0xffff00ff;
|
||||
colors[116]=0xffff5500;
|
||||
colors[117]=0xffff5555;
|
||||
colors[118]=0xffff55aa;
|
||||
colors[119]=0xffff55ff;
|
||||
colors[120]=0xffffaa00;
|
||||
colors[121]=0xffffaa55;
|
||||
colors[122]=0xffffaaaa;
|
||||
colors[123]=0xffffaaff;
|
||||
colors[124]=0xffffff00;
|
||||
colors[125]=0xffffff55;
|
||||
colors[126]=0xffffffaa;
|
||||
colors[127]=0xffffffff;
|
||||
colors[128]=0xff000000;
|
||||
colors[129]=0xff000055;
|
||||
colors[130]=0xff0000aa;
|
||||
colors[131]=0xff0000ff;
|
||||
colors[132]=0xff005500;
|
||||
colors[133]=0xff005555;
|
||||
colors[134]=0xff0055aa;
|
||||
colors[135]=0xff0055ff;
|
||||
colors[136]=0xff00aa00;
|
||||
colors[137]=0xff00aa55;
|
||||
colors[138]=0xff00aaaa;
|
||||
colors[139]=0xff00aaff;
|
||||
colors[140]=0xff00ff00;
|
||||
colors[141]=0xff00ff55;
|
||||
colors[142]=0xff00ffaa;
|
||||
colors[143]=0xff00ffff;
|
||||
colors[144]=0xff550000;
|
||||
colors[145]=0xff550055;
|
||||
colors[146]=0xff5500aa;
|
||||
colors[147]=0xff5500ff;
|
||||
colors[148]=0xff555500;
|
||||
colors[149]=0xff555555;
|
||||
colors[150]=0xff5555aa;
|
||||
colors[151]=0xff5555ff;
|
||||
colors[152]=0xff55aa00;
|
||||
colors[153]=0xff55aa55;
|
||||
colors[154]=0xff55aaaa;
|
||||
colors[155]=0xff55aaff;
|
||||
colors[156]=0xff55ff00;
|
||||
colors[157]=0xff55ff55;
|
||||
colors[158]=0xff55ffaa;
|
||||
colors[159]=0xff55ffff;
|
||||
colors[160]=0xffaa0000;
|
||||
colors[161]=0xffaa0055;
|
||||
colors[162]=0xffaa00aa;
|
||||
colors[163]=0xffaa00ff;
|
||||
colors[164]=0xffaa5500;
|
||||
colors[165]=0xffaa5555;
|
||||
colors[166]=0xffaa55aa;
|
||||
colors[167]=0xffaa55ff;
|
||||
colors[168]=0xffaaaa00;
|
||||
colors[169]=0xffaaaa55;
|
||||
colors[170]=0xffaaaaaa;
|
||||
colors[171]=0xffaaaaff;
|
||||
colors[172]=0xffaaff00;
|
||||
colors[173]=0xffaaff55;
|
||||
colors[174]=0xffaaffaa;
|
||||
colors[175]=0xffaaffff;
|
||||
colors[176]=0xffff0000;
|
||||
colors[177]=0xffff0055;
|
||||
colors[178]=0xffff00aa;
|
||||
colors[179]=0xffff00ff;
|
||||
colors[180]=0xffff5500;
|
||||
colors[181]=0xffff5555;
|
||||
colors[182]=0xffff55aa;
|
||||
colors[183]=0xffff55ff;
|
||||
colors[184]=0xffffaa00;
|
||||
colors[185]=0xffffaa55;
|
||||
colors[186]=0xffffaaaa;
|
||||
colors[187]=0xffffaaff;
|
||||
colors[188]=0xffffff00;
|
||||
colors[189]=0xffffff55;
|
||||
colors[190]=0xffffffaa;
|
||||
colors[191]=0xffffffff;
|
||||
colors[192]=0xff000000;
|
||||
colors[193]=0xff000055;
|
||||
colors[194]=0xff0000aa;
|
||||
colors[195]=0xff0000ff;
|
||||
colors[196]=0xff005500;
|
||||
colors[197]=0xff005555;
|
||||
colors[198]=0xff0055aa;
|
||||
colors[199]=0xff0055ff;
|
||||
colors[200]=0xff00aa00;
|
||||
colors[201]=0xff00aa55;
|
||||
colors[202]=0xff00aaaa;
|
||||
colors[203]=0xff00aaff;
|
||||
colors[204]=0xff00ff00;
|
||||
colors[205]=0xff00ff55;
|
||||
colors[206]=0xff00ffaa;
|
||||
colors[207]=0xff00ffff;
|
||||
colors[208]=0xff550000;
|
||||
colors[209]=0xff550055;
|
||||
colors[210]=0xff5500aa;
|
||||
colors[211]=0xff5500ff;
|
||||
colors[212]=0xff555500;
|
||||
colors[213]=0xff555555;
|
||||
colors[214]=0xff5555aa;
|
||||
colors[215]=0xff5555ff;
|
||||
colors[216]=0xff55aa00;
|
||||
colors[217]=0xff55aa55;
|
||||
colors[218]=0xff55aaaa;
|
||||
colors[219]=0xff55aaff;
|
||||
colors[220]=0xff55ff00;
|
||||
colors[221]=0xff55ff55;
|
||||
colors[222]=0xff55ffaa;
|
||||
colors[223]=0xff55ffff;
|
||||
colors[224]=0xffaa0000;
|
||||
colors[225]=0xffaa0055;
|
||||
colors[226]=0xffaa00aa;
|
||||
colors[227]=0xffaa00ff;
|
||||
colors[228]=0xffaa5500;
|
||||
colors[229]=0xffaa5555;
|
||||
colors[230]=0xffaa55aa;
|
||||
colors[231]=0xffaa55ff;
|
||||
colors[232]=0xffaaaa00;
|
||||
colors[233]=0xffaaaa55;
|
||||
colors[234]=0xffaaaaaa;
|
||||
colors[235]=0xffaaaaff;
|
||||
colors[236]=0xffaaff00;
|
||||
colors[237]=0xffaaff55;
|
||||
colors[238]=0xffaaffaa;
|
||||
colors[239]=0xffaaffff;
|
||||
colors[240]=0xffff0000;
|
||||
colors[241]=0xffff0055;
|
||||
colors[242]=0xffff00aa;
|
||||
colors[243]=0xffff00ff;
|
||||
colors[244]=0xffff5500;
|
||||
colors[245]=0xffff5555;
|
||||
colors[246]=0xffff55aa;
|
||||
colors[247]=0xffff55ff;
|
||||
colors[248]=0xffffaa00;
|
||||
colors[249]=0xffffaa55;
|
||||
colors[250]=0xffffaaaa;
|
||||
colors[251]=0xffffaaff;
|
||||
colors[252]=0xffffff00;
|
||||
colors[253]=0xffffff55;
|
||||
colors[254]=0xffffffaa;
|
||||
colors[255]=0xffffffff;
|
||||
|
||||
}
|
||||
}
|
||||
266
app/src/main/java/android/androidVNC/ColorModel8.java
Normal file
@@ -0,0 +1,266 @@
|
||||
package android.androidVNC;
|
||||
|
||||
public class ColorModel8 {
|
||||
|
||||
public final static int [] colors;
|
||||
|
||||
static {
|
||||
colors = new int[256];
|
||||
colors[0]=0xff000000;
|
||||
colors[1]=0xff0000ff;
|
||||
colors[2]=0xff00ff00;
|
||||
colors[3]=0xff00ffff;
|
||||
colors[4]=0xffff0000;
|
||||
colors[5]=0xffff00ff;
|
||||
colors[6]=0xffffff00;
|
||||
colors[7]=0xffffffff;
|
||||
colors[8]=0xff000000;
|
||||
colors[9]=0xff0000ff;
|
||||
colors[10]=0xff00ff00;
|
||||
colors[11]=0xff00ffff;
|
||||
colors[12]=0xffff0000;
|
||||
colors[13]=0xffff00ff;
|
||||
colors[14]=0xffffff00;
|
||||
colors[15]=0xffffffff;
|
||||
colors[16]=0xff000000;
|
||||
colors[17]=0xff0000ff;
|
||||
colors[18]=0xff00ff00;
|
||||
colors[19]=0xff00ffff;
|
||||
colors[20]=0xffff0000;
|
||||
colors[21]=0xffff00ff;
|
||||
colors[22]=0xffffff00;
|
||||
colors[23]=0xffffffff;
|
||||
colors[24]=0xff000000;
|
||||
colors[25]=0xff0000ff;
|
||||
colors[26]=0xff00ff00;
|
||||
colors[27]=0xff00ffff;
|
||||
colors[28]=0xffff0000;
|
||||
colors[29]=0xffff00ff;
|
||||
colors[30]=0xffffff00;
|
||||
colors[31]=0xffffffff;
|
||||
colors[32]=0xff000000;
|
||||
colors[33]=0xff0000ff;
|
||||
colors[34]=0xff00ff00;
|
||||
colors[35]=0xff00ffff;
|
||||
colors[36]=0xffff0000;
|
||||
colors[37]=0xffff00ff;
|
||||
colors[38]=0xffffff00;
|
||||
colors[39]=0xffffffff;
|
||||
colors[40]=0xff000000;
|
||||
colors[41]=0xff0000ff;
|
||||
colors[42]=0xff00ff00;
|
||||
colors[43]=0xff00ffff;
|
||||
colors[44]=0xffff0000;
|
||||
colors[45]=0xffff00ff;
|
||||
colors[46]=0xffffff00;
|
||||
colors[47]=0xffffffff;
|
||||
colors[48]=0xff000000;
|
||||
colors[49]=0xff0000ff;
|
||||
colors[50]=0xff00ff00;
|
||||
colors[51]=0xff00ffff;
|
||||
colors[52]=0xffff0000;
|
||||
colors[53]=0xffff00ff;
|
||||
colors[54]=0xffffff00;
|
||||
colors[55]=0xffffffff;
|
||||
colors[56]=0xff000000;
|
||||
colors[57]=0xff0000ff;
|
||||
colors[58]=0xff00ff00;
|
||||
colors[59]=0xff00ffff;
|
||||
colors[60]=0xffff0000;
|
||||
colors[61]=0xffff00ff;
|
||||
colors[62]=0xffffff00;
|
||||
colors[63]=0xffffffff;
|
||||
colors[64]=0xff000000;
|
||||
colors[65]=0xff0000ff;
|
||||
colors[66]=0xff00ff00;
|
||||
colors[67]=0xff00ffff;
|
||||
colors[68]=0xffff0000;
|
||||
colors[69]=0xffff00ff;
|
||||
colors[70]=0xffffff00;
|
||||
colors[71]=0xffffffff;
|
||||
colors[72]=0xff000000;
|
||||
colors[73]=0xff0000ff;
|
||||
colors[74]=0xff00ff00;
|
||||
colors[75]=0xff00ffff;
|
||||
colors[76]=0xffff0000;
|
||||
colors[77]=0xffff00ff;
|
||||
colors[78]=0xffffff00;
|
||||
colors[79]=0xffffffff;
|
||||
colors[80]=0xff000000;
|
||||
colors[81]=0xff0000ff;
|
||||
colors[82]=0xff00ff00;
|
||||
colors[83]=0xff00ffff;
|
||||
colors[84]=0xffff0000;
|
||||
colors[85]=0xffff00ff;
|
||||
colors[86]=0xffffff00;
|
||||
colors[87]=0xffffffff;
|
||||
colors[88]=0xff000000;
|
||||
colors[89]=0xff0000ff;
|
||||
colors[90]=0xff00ff00;
|
||||
colors[91]=0xff00ffff;
|
||||
colors[92]=0xffff0000;
|
||||
colors[93]=0xffff00ff;
|
||||
colors[94]=0xffffff00;
|
||||
colors[95]=0xffffffff;
|
||||
colors[96]=0xff000000;
|
||||
colors[97]=0xff0000ff;
|
||||
colors[98]=0xff00ff00;
|
||||
colors[99]=0xff00ffff;
|
||||
colors[100]=0xffff0000;
|
||||
colors[101]=0xffff00ff;
|
||||
colors[102]=0xffffff00;
|
||||
colors[103]=0xffffffff;
|
||||
colors[104]=0xff000000;
|
||||
colors[105]=0xff0000ff;
|
||||
colors[106]=0xff00ff00;
|
||||
colors[107]=0xff00ffff;
|
||||
colors[108]=0xffff0000;
|
||||
colors[109]=0xffff00ff;
|
||||
colors[110]=0xffffff00;
|
||||
colors[111]=0xffffffff;
|
||||
colors[112]=0xff000000;
|
||||
colors[113]=0xff0000ff;
|
||||
colors[114]=0xff00ff00;
|
||||
colors[115]=0xff00ffff;
|
||||
colors[116]=0xffff0000;
|
||||
colors[117]=0xffff00ff;
|
||||
colors[118]=0xffffff00;
|
||||
colors[119]=0xffffffff;
|
||||
colors[120]=0xff000000;
|
||||
colors[121]=0xff0000ff;
|
||||
colors[122]=0xff00ff00;
|
||||
colors[123]=0xff00ffff;
|
||||
colors[124]=0xffff0000;
|
||||
colors[125]=0xffff00ff;
|
||||
colors[126]=0xffffff00;
|
||||
colors[127]=0xffffffff;
|
||||
colors[128]=0xff000000;
|
||||
colors[129]=0xff0000ff;
|
||||
colors[130]=0xff00ff00;
|
||||
colors[131]=0xff00ffff;
|
||||
colors[132]=0xffff0000;
|
||||
colors[133]=0xffff00ff;
|
||||
colors[134]=0xffffff00;
|
||||
colors[135]=0xffffffff;
|
||||
colors[136]=0xff000000;
|
||||
colors[137]=0xff0000ff;
|
||||
colors[138]=0xff00ff00;
|
||||
colors[139]=0xff00ffff;
|
||||
colors[140]=0xffff0000;
|
||||
colors[141]=0xffff00ff;
|
||||
colors[142]=0xffffff00;
|
||||
colors[143]=0xffffffff;
|
||||
colors[144]=0xff000000;
|
||||
colors[145]=0xff0000ff;
|
||||
colors[146]=0xff00ff00;
|
||||
colors[147]=0xff00ffff;
|
||||
colors[148]=0xffff0000;
|
||||
colors[149]=0xffff00ff;
|
||||
colors[150]=0xffffff00;
|
||||
colors[151]=0xffffffff;
|
||||
colors[152]=0xff000000;
|
||||
colors[153]=0xff0000ff;
|
||||
colors[154]=0xff00ff00;
|
||||
colors[155]=0xff00ffff;
|
||||
colors[156]=0xffff0000;
|
||||
colors[157]=0xffff00ff;
|
||||
colors[158]=0xffffff00;
|
||||
colors[159]=0xffffffff;
|
||||
colors[160]=0xff000000;
|
||||
colors[161]=0xff0000ff;
|
||||
colors[162]=0xff00ff00;
|
||||
colors[163]=0xff00ffff;
|
||||
colors[164]=0xffff0000;
|
||||
colors[165]=0xffff00ff;
|
||||
colors[166]=0xffffff00;
|
||||
colors[167]=0xffffffff;
|
||||
colors[168]=0xff000000;
|
||||
colors[169]=0xff0000ff;
|
||||
colors[170]=0xff00ff00;
|
||||
colors[171]=0xff00ffff;
|
||||
colors[172]=0xffff0000;
|
||||
colors[173]=0xffff00ff;
|
||||
colors[174]=0xffffff00;
|
||||
colors[175]=0xffffffff;
|
||||
colors[176]=0xff000000;
|
||||
colors[177]=0xff0000ff;
|
||||
colors[178]=0xff00ff00;
|
||||
colors[179]=0xff00ffff;
|
||||
colors[180]=0xffff0000;
|
||||
colors[181]=0xffff00ff;
|
||||
colors[182]=0xffffff00;
|
||||
colors[183]=0xffffffff;
|
||||
colors[184]=0xff000000;
|
||||
colors[185]=0xff0000ff;
|
||||
colors[186]=0xff00ff00;
|
||||
colors[187]=0xff00ffff;
|
||||
colors[188]=0xffff0000;
|
||||
colors[189]=0xffff00ff;
|
||||
colors[190]=0xffffff00;
|
||||
colors[191]=0xffffffff;
|
||||
colors[192]=0xff000000;
|
||||
colors[193]=0xff0000ff;
|
||||
colors[194]=0xff00ff00;
|
||||
colors[195]=0xff00ffff;
|
||||
colors[196]=0xffff0000;
|
||||
colors[197]=0xffff00ff;
|
||||
colors[198]=0xffffff00;
|
||||
colors[199]=0xffffffff;
|
||||
colors[200]=0xff000000;
|
||||
colors[201]=0xff0000ff;
|
||||
colors[202]=0xff00ff00;
|
||||
colors[203]=0xff00ffff;
|
||||
colors[204]=0xffff0000;
|
||||
colors[205]=0xffff00ff;
|
||||
colors[206]=0xffffff00;
|
||||
colors[207]=0xffffffff;
|
||||
colors[208]=0xff000000;
|
||||
colors[209]=0xff0000ff;
|
||||
colors[210]=0xff00ff00;
|
||||
colors[211]=0xff00ffff;
|
||||
colors[212]=0xffff0000;
|
||||
colors[213]=0xffff00ff;
|
||||
colors[214]=0xffffff00;
|
||||
colors[215]=0xffffffff;
|
||||
colors[216]=0xff000000;
|
||||
colors[217]=0xff0000ff;
|
||||
colors[218]=0xff00ff00;
|
||||
colors[219]=0xff00ffff;
|
||||
colors[220]=0xffff0000;
|
||||
colors[221]=0xffff00ff;
|
||||
colors[222]=0xffffff00;
|
||||
colors[223]=0xffffffff;
|
||||
colors[224]=0xff000000;
|
||||
colors[225]=0xff0000ff;
|
||||
colors[226]=0xff00ff00;
|
||||
colors[227]=0xff00ffff;
|
||||
colors[228]=0xffff0000;
|
||||
colors[229]=0xffff00ff;
|
||||
colors[230]=0xffffff00;
|
||||
colors[231]=0xffffffff;
|
||||
colors[232]=0xff000000;
|
||||
colors[233]=0xff0000ff;
|
||||
colors[234]=0xff00ff00;
|
||||
colors[235]=0xff00ffff;
|
||||
colors[236]=0xffff0000;
|
||||
colors[237]=0xffff00ff;
|
||||
colors[238]=0xffffff00;
|
||||
colors[239]=0xffffffff;
|
||||
colors[240]=0xff000000;
|
||||
colors[241]=0xff0000ff;
|
||||
colors[242]=0xff00ff00;
|
||||
colors[243]=0xff00ffff;
|
||||
colors[244]=0xffff0000;
|
||||
colors[245]=0xffff00ff;
|
||||
colors[246]=0xffffff00;
|
||||
colors[247]=0xffffffff;
|
||||
colors[248]=0xff000000;
|
||||
colors[249]=0xff0000ff;
|
||||
colors[250]=0xff00ff00;
|
||||
colors[251]=0xff00ffff;
|
||||
colors[252]=0xffff0000;
|
||||
colors[253]=0xffff00ff;
|
||||
colors[254]=0xffffff00;
|
||||
colors[255]=0xffffffff;
|
||||
}
|
||||
}
|
||||
107
app/src/main/java/android/androidVNC/CompactBitmapData.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class CompactBitmapData extends AbstractBitmapData {
|
||||
|
||||
class CompactBitmapDrawable extends AbstractBitmapDrawable
|
||||
{
|
||||
CompactBitmapDrawable()
|
||||
{
|
||||
super(CompactBitmapData.this);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see android.graphics.drawable.DrawableContainer#draw(android.graphics.Canvas)
|
||||
*/
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
draw(canvas, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
CompactBitmapData(RfbProto rfb, VncCanvas c)
|
||||
{
|
||||
super(rfb,c);
|
||||
bitmapwidth=framebufferwidth;
|
||||
bitmapheight=framebufferheight;
|
||||
mbitmap = Bitmap.createBitmap(rfb.framebufferWidth, rfb.framebufferHeight, Bitmap.Config.RGB_565);
|
||||
memGraphics = new Canvas(mbitmap);
|
||||
bitmapPixels = new int[rfb.framebufferWidth * rfb.framebufferHeight];
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeFullUpdateRequest(boolean incremental) throws IOException {
|
||||
rfb.writeFramebufferUpdateRequest(0, 0, framebufferwidth, framebufferheight, incremental);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean validDraw(int x, int y, int w, int h) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
int offset(int x, int y) {
|
||||
return y * bitmapwidth + x;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#createDrawable()
|
||||
*/
|
||||
@Override
|
||||
AbstractBitmapDrawable createDrawable() {
|
||||
return new CompactBitmapDrawable();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#updateBitmap(int, int, int, int)
|
||||
*/
|
||||
@Override
|
||||
void updateBitmap(int x, int y, int w, int h) {
|
||||
mbitmap.setPixels(bitmapPixels, offset(x,y), bitmapwidth, x, y, w, h);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#copyRect(android.graphics.Rect, android.graphics.Rect, android.graphics.Paint)
|
||||
*/
|
||||
@Override
|
||||
void copyRect(Rect src, Rect dest, Paint paint) {
|
||||
memGraphics.drawBitmap(mbitmap, src, dest, paint);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#drawRect(int, int, int, int, android.graphics.Paint)
|
||||
*/
|
||||
@Override
|
||||
void drawRect(int x, int y, int w, int h, Paint paint) {
|
||||
memGraphics.drawRect(x, y, x + w, y + h, paint);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#scrollChanged(int, int)
|
||||
*/
|
||||
@Override
|
||||
void scrollChanged(int newx, int newy) {
|
||||
// Don't need to do anything here
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#syncScroll()
|
||||
*/
|
||||
@Override
|
||||
void syncScroll() {
|
||||
// Don't need anything here either
|
||||
|
||||
}
|
||||
}
|
||||
89
app/src/main/java/android/androidVNC/ConnectionBean.java
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
|
||||
import com.antlersoft.android.dbimpl.NewInstance;
|
||||
|
||||
import java.lang.Comparable;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class ConnectionBean extends AbstractConnectionBean implements Comparable<ConnectionBean> {
|
||||
static final NewInstance<ConnectionBean> newInstance=new NewInstance<ConnectionBean>() {
|
||||
public ConnectionBean get() { return new ConnectionBean(); }
|
||||
};
|
||||
ConnectionBean()
|
||||
{
|
||||
set_Id(0);
|
||||
setAddress("");
|
||||
setPassword("");
|
||||
setKeepPassword(true);
|
||||
setNickname("");
|
||||
setUserName("");
|
||||
setPort(5900);
|
||||
setColorModel(COLORMODEL.C64.nameString());
|
||||
setScaleMode(ScaleType.MATRIX);
|
||||
setInputMode(VncCanvasActivity.TOUCH_ZOOM_MODE);
|
||||
setRepeaterId("");
|
||||
setMetaListId(1);
|
||||
}
|
||||
|
||||
boolean isNew()
|
||||
{
|
||||
return get_Id()== 0;
|
||||
}
|
||||
|
||||
void save(SQLiteDatabase database) {
|
||||
ContentValues values=Gen_getValues();
|
||||
values.remove(GEN_FIELD__ID);
|
||||
if ( ! getKeepPassword()) {
|
||||
values.put(GEN_FIELD_PASSWORD, "");
|
||||
}
|
||||
if ( isNew()) {
|
||||
set_Id(database.insert(GEN_TABLE_NAME, null, values));
|
||||
} else {
|
||||
database.update(GEN_TABLE_NAME, values, GEN_FIELD__ID + " = ?", new String[] { Long.toString(get_Id()) });
|
||||
}
|
||||
}
|
||||
|
||||
ScaleType getScaleMode()
|
||||
{
|
||||
return ScaleType.valueOf(getScaleModeAsString());
|
||||
}
|
||||
|
||||
void setScaleMode(ScaleType value)
|
||||
{
|
||||
setScaleModeAsString(value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if ( isNew())
|
||||
{
|
||||
return "New";
|
||||
}
|
||||
return getNickname()+":"+getAddress()+":"+getPort();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(ConnectionBean another) {
|
||||
int result = getNickname().compareTo(another.getNickname());
|
||||
if (result == 0) {
|
||||
result = getAddress().compareTo(another.getAddress());
|
||||
if ( result == 0) {
|
||||
result = getPort() - another.getPort();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
120
app/src/main/java/android/androidVNC/ConnectionListActivity.java
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* This 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 software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*
|
||||
* Copyright 2009,2010 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.*;
|
||||
import android.content.Intent.*;
|
||||
import android.database.*;
|
||||
import android.net.*;
|
||||
import android.os.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
public class ConnectionListActivity extends ListActivity {
|
||||
|
||||
VncDatabase database;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
database = new VncDatabase(this);
|
||||
|
||||
// Query for all people contacts using the Contacts.People convenience class.
|
||||
// Put a managed wrapper around the retrieved cursor so we don't have to worry about
|
||||
// requerying or closing it as the activity changes state.
|
||||
Cursor mCursor = database.getReadableDatabase().query(ConnectionBean.GEN_TABLE_NAME, new String[] {
|
||||
ConnectionBean.GEN_FIELD__ID,
|
||||
ConnectionBean.GEN_FIELD_NICKNAME,
|
||||
ConnectionBean.GEN_FIELD_USERNAME,
|
||||
ConnectionBean.GEN_FIELD_ADDRESS,
|
||||
ConnectionBean.GEN_FIELD_PORT,
|
||||
ConnectionBean.GEN_FIELD_REPEATERID },
|
||||
ConnectionBean.GEN_FIELD_KEEPPASSWORD + " <> 0", null, null, null, ConnectionBean.GEN_FIELD_NICKNAME);
|
||||
startManagingCursor(mCursor);
|
||||
|
||||
// Now create a new list adapter bound to the cursor.
|
||||
// SimpleListAdapter is designed for binding to a Cursor.
|
||||
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
|
||||
this, // Context.
|
||||
R.layout.connection_list,
|
||||
mCursor, // Pass in the cursor to bind to.
|
||||
new String[] {
|
||||
ConnectionBean.GEN_FIELD_NICKNAME,
|
||||
ConnectionBean.GEN_FIELD_ADDRESS,
|
||||
ConnectionBean.GEN_FIELD_PORT,
|
||||
ConnectionBean.GEN_FIELD_REPEATERID }, // Array of cursor columns to bind to.
|
||||
new int[] {
|
||||
R.id.list_text_nickname,
|
||||
R.id.list_text_address,
|
||||
R.id.list_text_port,
|
||||
R.id.list_text_repeater
|
||||
}); // Parallel array of which template objects to bind to those columns.
|
||||
|
||||
// Bind to our new adapter.
|
||||
setListAdapter(adapter);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.ListActivity#onListItemClick(android.widget.ListView, android.view.View, int, long)
|
||||
*/
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
ConnectionBean connection = new ConnectionBean();
|
||||
if (connection.Gen_read(database.getReadableDatabase(), id))
|
||||
{
|
||||
// create shortcut if requested
|
||||
ShortcutIconResource icon = Intent.ShortcutIconResource.fromContext(this, R.drawable.ic_xvnc);
|
||||
|
||||
Intent intent = new Intent();
|
||||
|
||||
Intent launchIntent = new Intent(this,VncCanvasActivity.class);
|
||||
Uri.Builder builder = new Uri.Builder();
|
||||
builder.authority(VncConstants.CONNECTION + ":" + connection.get_Id());
|
||||
builder.scheme("vnc");
|
||||
launchIntent.setData(builder.build());
|
||||
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, connection.getNickname());
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
|
||||
|
||||
setResult(RESULT_OK, intent);
|
||||
}
|
||||
else
|
||||
setResult(RESULT_CANCELED);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Activity#onDestroy()
|
||||
*/
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
database.close();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
}
|
||||
12
app/src/main/java/android/androidVNC/ConnectionSettable.java
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
*
|
||||
*/
|
||||
interface ConnectionSettable {
|
||||
void setConnection(ConnectionBean connection);
|
||||
}
|
||||
183
app/src/main/java/android/androidVNC/DH.java
Normal file
@@ -0,0 +1,183 @@
|
||||
package android.androidVNC;
|
||||
// CRYPTO LIBRARY FOR EXCHANGING KEYS
|
||||
// USING THE DIFFIE-HELLMAN KEY EXCHANGE PROTOCOL
|
||||
|
||||
// The diffie-hellman can be used to securely exchange keys
|
||||
// between parties, where a third party eavesdropper given
|
||||
// the values being transmitted cannot determine the key.
|
||||
|
||||
// Implemented by Lee Griffiths, Jan 2004.
|
||||
// This software is freeware, you may use it to your discretion,
|
||||
// however by doing so you take full responsibility for any damage
|
||||
// it may cause.
|
||||
|
||||
// Hope you find it useful, even if you just use some of the functions
|
||||
// out of it like the prime number generator and the XtoYmodN function.
|
||||
|
||||
// It would be great if you could send me emails to: lee.griffiths@first4internet.co.uk
|
||||
// with any suggestions, comments, or questions!
|
||||
|
||||
// Enjoy.
|
||||
|
||||
// Adopted to ms-logon for ultravnc and ported to Java by marscha, 2006.
|
||||
|
||||
//import java.lang.Math;
|
||||
|
||||
public class DH {
|
||||
|
||||
public DH() {
|
||||
maxNum = (((long) 1) << DH_MAX_BITS) - 1;
|
||||
}
|
||||
|
||||
public DH(long generator, long modulus) throws Exception {
|
||||
maxNum = (((long) 1) << DH_MAX_BITS) - 1;
|
||||
if (generator >= maxNum || modulus >= maxNum)
|
||||
throw new Exception("Modulus or generator too large.");
|
||||
gen = generator;
|
||||
mod = modulus;
|
||||
}
|
||||
|
||||
private long rng(long limit) {
|
||||
return (long) (java.lang.Math.random() * limit);
|
||||
}
|
||||
|
||||
//Performs the miller-rabin primality test on a guessed prime n.
|
||||
//trials is the number of attempts to verify this, because the function
|
||||
//is not 100% accurate it may be a composite. However setting the trial
|
||||
//value to around 5 should guarantee success even with very large primes
|
||||
private boolean millerRabin (long n, int trials) {
|
||||
long a = 0;
|
||||
|
||||
for (int i = 0; i < trials; i++) {
|
||||
a = rng(n - 3) + 2;// gets random value in [2..n-1]
|
||||
if (XpowYmodN(a, n - 1, n) != 1) return false; //n composite, return false
|
||||
}
|
||||
return true; // n probably prime
|
||||
}
|
||||
|
||||
//Generates a large prime number by
|
||||
//choosing a randomly large integer, and ensuring the value is odd
|
||||
//then uses the miller-rabin primality test on it to see if it is prime
|
||||
//if not the value gets increased until it is prime
|
||||
private long generatePrime() {
|
||||
long prime = 0;
|
||||
|
||||
do {
|
||||
long start = rng(maxNum);
|
||||
prime = tryToGeneratePrime(start);
|
||||
} while (prime == 0);
|
||||
return prime;
|
||||
}
|
||||
|
||||
private long tryToGeneratePrime(long prime) {
|
||||
//ensure it is an odd number
|
||||
if ((prime & 1) == 0)
|
||||
prime += 1;
|
||||
|
||||
long cnt = 0;
|
||||
while (!millerRabin(prime, 25) && (cnt++ < DH_RANGE) && prime < maxNum) {
|
||||
prime += 2;
|
||||
if ((prime % 3) == 0) prime += 2;
|
||||
}
|
||||
return (cnt >= DH_RANGE || prime >= maxNum) ? 0 : prime;
|
||||
}
|
||||
|
||||
//Raises X to the power Y in modulus N
|
||||
//the values of X, Y, and N can be massive, and this can be
|
||||
//achieved by first calculating X to the power of 2 then
|
||||
//using power chaining over modulus N
|
||||
private long XpowYmodN(long x, long y, long N) {
|
||||
long result = 1;
|
||||
final long oneShift63 = ((long) 1) << 63;
|
||||
|
||||
for (int i = 0; i < 64; y <<= 1, i++){
|
||||
result = result * result % N;
|
||||
if ((y & oneShift63) != 0)
|
||||
result = result * x % N;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void createKeys() {
|
||||
gen = generatePrime();
|
||||
mod = generatePrime();
|
||||
|
||||
if (gen > mod) {
|
||||
long swap = gen;
|
||||
gen = mod;
|
||||
mod = swap;
|
||||
}
|
||||
}
|
||||
|
||||
public long createInterKey() {
|
||||
priv = rng(maxNum);
|
||||
return pub = XpowYmodN(gen,priv,mod);
|
||||
}
|
||||
|
||||
public long createEncryptionKey(long interKey) throws Exception {
|
||||
if (interKey >= maxNum){
|
||||
throw new Exception("interKey too large");
|
||||
}
|
||||
return key = XpowYmodN(interKey,priv,mod);
|
||||
}
|
||||
|
||||
|
||||
public long getValue(int flags) {
|
||||
switch (flags) {
|
||||
case DH_MOD:
|
||||
return mod;
|
||||
case DH_GEN:
|
||||
return gen;
|
||||
case DH_PRIV:
|
||||
return priv;
|
||||
case DH_PUB:
|
||||
return pub;
|
||||
case DH_KEY:
|
||||
return key;
|
||||
default:
|
||||
return (long) 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int bits(long number){
|
||||
for (int i = 0; i < 64; i++){
|
||||
number /= 2;
|
||||
if (number < 2) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static byte[] longToBytes(long number) {
|
||||
byte[] bytes = new byte[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
bytes[i] = (byte) (0xff & (number >> (8 * (7 - i))));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static long bytesToLong(byte[] bytes) {
|
||||
long result = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
result <<= 8;
|
||||
result += (byte) bytes[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private long gen;
|
||||
private long mod;
|
||||
private long priv;
|
||||
private long pub;
|
||||
private long key;
|
||||
private long maxNum;
|
||||
|
||||
private static final int DH_MAX_BITS = 31;
|
||||
private static final int DH_RANGE = 100;
|
||||
|
||||
private static final int DH_MOD = 1;
|
||||
private static final int DH_GEN = 2;
|
||||
private static final int DH_PRIV = 3;
|
||||
private static final int DH_PUB = 4;
|
||||
private static final int DH_KEY = 5;
|
||||
|
||||
}
|
||||
115
app/src/main/java/android/androidVNC/DPadMouseKeyHandler.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.os.Handler;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* Input handlers delegate to this class to handle keystrokes; this detects keystrokes
|
||||
* from the DPad and uses them to perform mouse actions; other keystrokes are passed to
|
||||
* VncCanvasActivity.defaultKeyXXXHandler
|
||||
*
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class DPadMouseKeyHandler {
|
||||
private MouseMover mouseMover;
|
||||
private boolean mouseDown;
|
||||
private VncCanvasActivity activity;
|
||||
private VncCanvas canvas;
|
||||
private boolean isMoving;
|
||||
|
||||
DPadMouseKeyHandler(VncCanvasActivity activity, Handler handler)
|
||||
{
|
||||
this.activity = activity;
|
||||
canvas = activity.vncCanvas;
|
||||
mouseMover = new MouseMover(activity, handler);
|
||||
}
|
||||
|
||||
public boolean onKeyDown(int keyCode, KeyEvent evt) {
|
||||
int xv = 0;
|
||||
int yv = 0;
|
||||
boolean result = true;
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
xv = -1;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
xv = 1;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
yv = -1;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
yv = 1;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
if (!mouseDown) {
|
||||
mouseDown = true;
|
||||
result = canvas.processPointerEvent(canvas.mouseX, canvas.mouseY, MotionEvent.ACTION_DOWN, evt.getMetaState(), mouseDown, canvas.cameraButtonDown);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = activity.defaultKeyDownHandler(keyCode, evt);
|
||||
break;
|
||||
}
|
||||
if ((xv != 0 || yv != 0) && !isMoving) {
|
||||
final int x = xv;
|
||||
final int y = yv;
|
||||
isMoving = true;
|
||||
mouseMover.start(x, y, new Panner.VelocityUpdater() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see android.androidVNC.Panner.VelocityUpdater#updateVelocity(android.graphics.Point,
|
||||
* long)
|
||||
*/
|
||||
@Override
|
||||
public boolean updateVelocity(PointF p, long interval) {
|
||||
double scale = (1.2 * (double) interval / 50.0);
|
||||
if (Math.abs(p.x) < 500)
|
||||
p.x += (int) (scale * x);
|
||||
if (Math.abs(p.y) < 500)
|
||||
p.y += (int) (scale * y);
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
canvas.processPointerEvent(canvas.mouseX + x, canvas.mouseY + y, MotionEvent.ACTION_MOVE, evt.getMetaState(), mouseDown, canvas.cameraButtonDown);
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean onKeyUp(int keyCode, KeyEvent evt) {
|
||||
boolean result = false;
|
||||
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
mouseMover.stop();
|
||||
isMoving = false;
|
||||
result = true;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
if (mouseDown) {
|
||||
mouseDown = false;
|
||||
result = canvas.processPointerEvent(canvas.mouseX, canvas.mouseY, MotionEvent.ACTION_UP, evt.getMetaState(), mouseDown, canvas.cameraButtonDown);
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = activity.defaultKeyUpHandler(keyCode, evt);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
539
app/src/main/java/android/androidVNC/DesCipher.java
Normal file
@@ -0,0 +1,539 @@
|
||||
//
|
||||
// This DES class has been extracted from package Acme.Crypto for use in VNC.
|
||||
// The bytebit[] array has been reversed so that the most significant bit
|
||||
// in each byte of the key is ignored, not the least significant. Also the
|
||||
// unnecessary odd parity code has been removed.
|
||||
//
|
||||
// These changes are:
|
||||
// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
|
||||
//
|
||||
// This software 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.
|
||||
//
|
||||
|
||||
// DesCipher - the DES encryption method
|
||||
//
|
||||
// The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
|
||||
//
|
||||
// Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software
|
||||
// and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
|
||||
// without fee is hereby granted, provided that this copyright notice is kept
|
||||
// intact.
|
||||
//
|
||||
// WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
|
||||
// OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
|
||||
// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
|
||||
// DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
//
|
||||
// THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
|
||||
// CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
|
||||
// PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
|
||||
// NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
|
||||
// SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
|
||||
// SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
|
||||
// PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP
|
||||
// SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
|
||||
// HIGH RISK ACTIVITIES.
|
||||
//
|
||||
//
|
||||
// The rest is:
|
||||
//
|
||||
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
// SUCH DAMAGE.
|
||||
//
|
||||
// Visit the ACME Labs Java page for up-to-date versions of this and other
|
||||
// fine Java utilities: http://www.acme.com/java/
|
||||
|
||||
/// The DES encryption method.
|
||||
// <P>
|
||||
// This is surprisingly fast, for pure Java. On a SPARC 20, wrapped
|
||||
// in Acme.Crypto.EncryptedOutputStream or Acme.Crypto.EncryptedInputStream,
|
||||
// it does around 7000 bytes/second.
|
||||
// <P>
|
||||
// Most of this code is by Dave Zimmerman <dzimm@widget.com>, and is
|
||||
// Copyright (c) 1996 Widget Workshop, Inc. See the source file for details.
|
||||
// <P>
|
||||
// <A HREF="/resources/classes/Acme/Crypto/DesCipher.java">Fetch the software.</A><BR>
|
||||
// <A HREF="/resources/classes/Acme.tar.Z">Fetch the entire Acme package.</A>
|
||||
// <P>
|
||||
// @see Des3Cipher
|
||||
// @see EncryptedOutputStream
|
||||
// @see EncryptedInputStream
|
||||
|
||||
package android.androidVNC;
|
||||
|
||||
//- import java.io.*;
|
||||
|
||||
|
||||
public class DesCipher
|
||||
{
|
||||
|
||||
// Constructor, byte-array key.
|
||||
public DesCipher( byte[] key )
|
||||
{
|
||||
setKey( key );
|
||||
}
|
||||
|
||||
// Key routines.
|
||||
|
||||
private int[] encryptKeys = new int[32];
|
||||
private int[] decryptKeys = new int[32];
|
||||
|
||||
/// Set the key.
|
||||
public void setKey( byte[] key )
|
||||
{
|
||||
deskey( key, true, encryptKeys );
|
||||
deskey( key, false, decryptKeys );
|
||||
}
|
||||
|
||||
// Turn an 8-byte key into internal keys.
|
||||
private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL )
|
||||
{
|
||||
int i, j, l, m, n;
|
||||
int[] pc1m = new int[56];
|
||||
int[] pcr = new int[56];
|
||||
int[] kn = new int[32];
|
||||
|
||||
for ( j = 0; j < 56; ++j )
|
||||
{
|
||||
l = pc1[j];
|
||||
m = l & 07;
|
||||
pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0;
|
||||
}
|
||||
|
||||
for ( i = 0; i < 16; ++i )
|
||||
{
|
||||
if ( encrypting )
|
||||
m = i << 1;
|
||||
else
|
||||
m = (15-i) << 1;
|
||||
n = m+1;
|
||||
kn[m] = kn[n] = 0;
|
||||
for ( j = 0; j < 28; ++j )
|
||||
{
|
||||
l = j+totrot[i];
|
||||
if ( l < 28 )
|
||||
pcr[j] = pc1m[l];
|
||||
else
|
||||
pcr[j] = pc1m[l-28];
|
||||
}
|
||||
for ( j=28; j < 56; ++j )
|
||||
{
|
||||
l = j+totrot[i];
|
||||
if ( l < 56 )
|
||||
pcr[j] = pc1m[l];
|
||||
else
|
||||
pcr[j] = pc1m[l-28];
|
||||
}
|
||||
for ( j = 0; j < 24; ++j )
|
||||
{
|
||||
if ( pcr[pc2[j]] != 0 )
|
||||
kn[m] |= bigbyte[j];
|
||||
if ( pcr[pc2[j+24]] != 0 )
|
||||
kn[n] |= bigbyte[j];
|
||||
}
|
||||
}
|
||||
cookey( kn, KnL );
|
||||
}
|
||||
|
||||
private void cookey( int[] raw, int KnL[] )
|
||||
{
|
||||
int raw0, raw1;
|
||||
int rawi, KnLi;
|
||||
int i;
|
||||
|
||||
for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i )
|
||||
{
|
||||
raw0 = raw[rawi++];
|
||||
raw1 = raw[rawi++];
|
||||
KnL[KnLi] = (raw0 & 0x00fc0000) << 6;
|
||||
KnL[KnLi] |= (raw0 & 0x00000fc0) << 10;
|
||||
KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
|
||||
KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
|
||||
++KnLi;
|
||||
KnL[KnLi] = (raw0 & 0x0003f000) << 12;
|
||||
KnL[KnLi] |= (raw0 & 0x0000003f) << 16;
|
||||
KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4;
|
||||
KnL[KnLi] |= (raw1 & 0x0000003f);
|
||||
++KnLi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Block encryption routines.
|
||||
|
||||
private int[] tempInts = new int[2];
|
||||
|
||||
/// Encrypt a block of eight bytes.
|
||||
public void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff )
|
||||
{
|
||||
squashBytesToInts( clearText, clearOff, tempInts, 0, 2 );
|
||||
des( tempInts, tempInts, encryptKeys );
|
||||
spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 );
|
||||
}
|
||||
|
||||
/// Decrypt a block of eight bytes.
|
||||
public void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff )
|
||||
{
|
||||
squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 );
|
||||
des( tempInts, tempInts, decryptKeys );
|
||||
spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 );
|
||||
}
|
||||
|
||||
// Encrypt a text which is a multiple of 8 bytes.
|
||||
public void encryptText(byte[] clearText, byte[] cipherText, byte[] key)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for(i=0; i<8; i++)
|
||||
{
|
||||
clearText[i] ^= key[i];
|
||||
}
|
||||
encrypt(clearText, 0, cipherText, 0);
|
||||
for(i=8; i<clearText.length; i+=8)
|
||||
{
|
||||
for(j=0; j<8; j++)
|
||||
{
|
||||
clearText[i+j] ^= cipherText[i+j-8];
|
||||
}
|
||||
encrypt(clearText, i, cipherText, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Decrypt a text which is a multiple of 8 bytes.
|
||||
public void decryptText(byte[] cipherText, byte[] clearText, byte[] key)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for(i=cipherText.length-8; i>0; i-=8)
|
||||
{
|
||||
decrypt(cipherText, i, clearText, i);
|
||||
for(j=0; j<8; j++)
|
||||
{
|
||||
clearText[i+j] ^= cipherText[i+j-8];
|
||||
}
|
||||
}
|
||||
/* i = 0 */
|
||||
decrypt(cipherText, 0, clearText, 0);
|
||||
for(i=0; i<8; i++)
|
||||
{
|
||||
clearText[i] ^= key[i];
|
||||
}
|
||||
}
|
||||
|
||||
// The DES function.
|
||||
private void des( int[] inInts, int[] outInts, int[] keys )
|
||||
{
|
||||
int fval, work, right, leftt;
|
||||
int round;
|
||||
int keysi = 0;
|
||||
|
||||
leftt = inInts[0];
|
||||
right = inInts[1];
|
||||
|
||||
work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f;
|
||||
right ^= work;
|
||||
leftt ^= (work << 4);
|
||||
|
||||
work = ((leftt >>> 16) ^ right) & 0x0000ffff;
|
||||
right ^= work;
|
||||
leftt ^= (work << 16);
|
||||
|
||||
work = ((right >>> 2) ^ leftt) & 0x33333333;
|
||||
leftt ^= work;
|
||||
right ^= (work << 2);
|
||||
|
||||
work = ((right >>> 8) ^ leftt) & 0x00ff00ff;
|
||||
leftt ^= work;
|
||||
right ^= (work << 8);
|
||||
right = (right << 1) | ((right >>> 31) & 1);
|
||||
|
||||
work = (leftt ^ right) & 0xaaaaaaaa;
|
||||
leftt ^= work;
|
||||
right ^= work;
|
||||
leftt = (leftt << 1) | ((leftt >>> 31) & 1);
|
||||
|
||||
for ( round = 0; round < 8; ++round )
|
||||
{
|
||||
work = (right << 28) | (right >>> 4);
|
||||
work ^= keys[keysi++];
|
||||
fval = SP7[ work & 0x0000003f ];
|
||||
fval |= SP5[(work >>> 8) & 0x0000003f ];
|
||||
fval |= SP3[(work >>> 16) & 0x0000003f ];
|
||||
fval |= SP1[(work >>> 24) & 0x0000003f ];
|
||||
work = right ^ keys[keysi++];
|
||||
fval |= SP8[ work & 0x0000003f ];
|
||||
fval |= SP6[(work >>> 8) & 0x0000003f ];
|
||||
fval |= SP4[(work >>> 16) & 0x0000003f ];
|
||||
fval |= SP2[(work >>> 24) & 0x0000003f ];
|
||||
leftt ^= fval;
|
||||
work = (leftt << 28) | (leftt >>> 4);
|
||||
work ^= keys[keysi++];
|
||||
fval = SP7[ work & 0x0000003f ];
|
||||
fval |= SP5[(work >>> 8) & 0x0000003f ];
|
||||
fval |= SP3[(work >>> 16) & 0x0000003f ];
|
||||
fval |= SP1[(work >>> 24) & 0x0000003f ];
|
||||
work = leftt ^ keys[keysi++];
|
||||
fval |= SP8[ work & 0x0000003f ];
|
||||
fval |= SP6[(work >>> 8) & 0x0000003f ];
|
||||
fval |= SP4[(work >>> 16) & 0x0000003f ];
|
||||
fval |= SP2[(work >>> 24) & 0x0000003f ];
|
||||
right ^= fval;
|
||||
}
|
||||
|
||||
right = (right << 31) | (right >>> 1);
|
||||
work = (leftt ^ right) & 0xaaaaaaaa;
|
||||
leftt ^= work;
|
||||
right ^= work;
|
||||
leftt = (leftt << 31) | (leftt >>> 1);
|
||||
work = ((leftt >>> 8) ^ right) & 0x00ff00ff;
|
||||
right ^= work;
|
||||
leftt ^= (work << 8);
|
||||
work = ((leftt >>> 2) ^ right) & 0x33333333;
|
||||
right ^= work;
|
||||
leftt ^= (work << 2);
|
||||
work = ((right >>> 16) ^ leftt) & 0x0000ffff;
|
||||
leftt ^= work;
|
||||
right ^= (work << 16);
|
||||
work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f;
|
||||
leftt ^= work;
|
||||
right ^= (work << 4);
|
||||
outInts[0] = right;
|
||||
outInts[1] = leftt;
|
||||
}
|
||||
|
||||
|
||||
// Tables, permutations, S-boxes, etc.
|
||||
|
||||
private static byte[] bytebit = {
|
||||
(byte)0x01, (byte)0x02, (byte)0x04, (byte)0x08,
|
||||
(byte)0x10, (byte)0x20, (byte)0x40, (byte)0x80
|
||||
};
|
||||
private static int[] bigbyte = {
|
||||
0x800000, 0x400000, 0x200000, 0x100000,
|
||||
0x080000, 0x040000, 0x020000, 0x010000,
|
||||
0x008000, 0x004000, 0x002000, 0x001000,
|
||||
0x000800, 0x000400, 0x000200, 0x000100,
|
||||
0x000080, 0x000040, 0x000020, 0x000010,
|
||||
0x000008, 0x000004, 0x000002, 0x000001
|
||||
};
|
||||
private static byte[] pc1 = {
|
||||
(byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8,
|
||||
(byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17,
|
||||
(byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26,
|
||||
(byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35,
|
||||
(byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14,
|
||||
(byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21,
|
||||
(byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28,
|
||||
(byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3
|
||||
};
|
||||
private static int[] totrot = {
|
||||
1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
|
||||
};
|
||||
|
||||
private static byte[] pc2 = {
|
||||
(byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4,
|
||||
(byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9,
|
||||
(byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7,
|
||||
(byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1,
|
||||
(byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54,
|
||||
(byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47,
|
||||
(byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52,
|
||||
(byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31,
|
||||
};
|
||||
|
||||
private static int[] SP1 = {
|
||||
0x01010400, 0x00000000, 0x00010000, 0x01010404,
|
||||
0x01010004, 0x00010404, 0x00000004, 0x00010000,
|
||||
0x00000400, 0x01010400, 0x01010404, 0x00000400,
|
||||
0x01000404, 0x01010004, 0x01000000, 0x00000004,
|
||||
0x00000404, 0x01000400, 0x01000400, 0x00010400,
|
||||
0x00010400, 0x01010000, 0x01010000, 0x01000404,
|
||||
0x00010004, 0x01000004, 0x01000004, 0x00010004,
|
||||
0x00000000, 0x00000404, 0x00010404, 0x01000000,
|
||||
0x00010000, 0x01010404, 0x00000004, 0x01010000,
|
||||
0x01010400, 0x01000000, 0x01000000, 0x00000400,
|
||||
0x01010004, 0x00010000, 0x00010400, 0x01000004,
|
||||
0x00000400, 0x00000004, 0x01000404, 0x00010404,
|
||||
0x01010404, 0x00010004, 0x01010000, 0x01000404,
|
||||
0x01000004, 0x00000404, 0x00010404, 0x01010400,
|
||||
0x00000404, 0x01000400, 0x01000400, 0x00000000,
|
||||
0x00010004, 0x00010400, 0x00000000, 0x01010004
|
||||
};
|
||||
private static int[] SP2 = {
|
||||
0x80108020, 0x80008000, 0x00008000, 0x00108020,
|
||||
0x00100000, 0x00000020, 0x80100020, 0x80008020,
|
||||
0x80000020, 0x80108020, 0x80108000, 0x80000000,
|
||||
0x80008000, 0x00100000, 0x00000020, 0x80100020,
|
||||
0x00108000, 0x00100020, 0x80008020, 0x00000000,
|
||||
0x80000000, 0x00008000, 0x00108020, 0x80100000,
|
||||
0x00100020, 0x80000020, 0x00000000, 0x00108000,
|
||||
0x00008020, 0x80108000, 0x80100000, 0x00008020,
|
||||
0x00000000, 0x00108020, 0x80100020, 0x00100000,
|
||||
0x80008020, 0x80100000, 0x80108000, 0x00008000,
|
||||
0x80100000, 0x80008000, 0x00000020, 0x80108020,
|
||||
0x00108020, 0x00000020, 0x00008000, 0x80000000,
|
||||
0x00008020, 0x80108000, 0x00100000, 0x80000020,
|
||||
0x00100020, 0x80008020, 0x80000020, 0x00100020,
|
||||
0x00108000, 0x00000000, 0x80008000, 0x00008020,
|
||||
0x80000000, 0x80100020, 0x80108020, 0x00108000
|
||||
};
|
||||
private static int[] SP3 = {
|
||||
0x00000208, 0x08020200, 0x00000000, 0x08020008,
|
||||
0x08000200, 0x00000000, 0x00020208, 0x08000200,
|
||||
0x00020008, 0x08000008, 0x08000008, 0x00020000,
|
||||
0x08020208, 0x00020008, 0x08020000, 0x00000208,
|
||||
0x08000000, 0x00000008, 0x08020200, 0x00000200,
|
||||
0x00020200, 0x08020000, 0x08020008, 0x00020208,
|
||||
0x08000208, 0x00020200, 0x00020000, 0x08000208,
|
||||
0x00000008, 0x08020208, 0x00000200, 0x08000000,
|
||||
0x08020200, 0x08000000, 0x00020008, 0x00000208,
|
||||
0x00020000, 0x08020200, 0x08000200, 0x00000000,
|
||||
0x00000200, 0x00020008, 0x08020208, 0x08000200,
|
||||
0x08000008, 0x00000200, 0x00000000, 0x08020008,
|
||||
0x08000208, 0x00020000, 0x08000000, 0x08020208,
|
||||
0x00000008, 0x00020208, 0x00020200, 0x08000008,
|
||||
0x08020000, 0x08000208, 0x00000208, 0x08020000,
|
||||
0x00020208, 0x00000008, 0x08020008, 0x00020200
|
||||
};
|
||||
private static int[] SP4 = {
|
||||
0x00802001, 0x00002081, 0x00002081, 0x00000080,
|
||||
0x00802080, 0x00800081, 0x00800001, 0x00002001,
|
||||
0x00000000, 0x00802000, 0x00802000, 0x00802081,
|
||||
0x00000081, 0x00000000, 0x00800080, 0x00800001,
|
||||
0x00000001, 0x00002000, 0x00800000, 0x00802001,
|
||||
0x00000080, 0x00800000, 0x00002001, 0x00002080,
|
||||
0x00800081, 0x00000001, 0x00002080, 0x00800080,
|
||||
0x00002000, 0x00802080, 0x00802081, 0x00000081,
|
||||
0x00800080, 0x00800001, 0x00802000, 0x00802081,
|
||||
0x00000081, 0x00000000, 0x00000000, 0x00802000,
|
||||
0x00002080, 0x00800080, 0x00800081, 0x00000001,
|
||||
0x00802001, 0x00002081, 0x00002081, 0x00000080,
|
||||
0x00802081, 0x00000081, 0x00000001, 0x00002000,
|
||||
0x00800001, 0x00002001, 0x00802080, 0x00800081,
|
||||
0x00002001, 0x00002080, 0x00800000, 0x00802001,
|
||||
0x00000080, 0x00800000, 0x00002000, 0x00802080
|
||||
};
|
||||
private static int[] SP5 = {
|
||||
0x00000100, 0x02080100, 0x02080000, 0x42000100,
|
||||
0x00080000, 0x00000100, 0x40000000, 0x02080000,
|
||||
0x40080100, 0x00080000, 0x02000100, 0x40080100,
|
||||
0x42000100, 0x42080000, 0x00080100, 0x40000000,
|
||||
0x02000000, 0x40080000, 0x40080000, 0x00000000,
|
||||
0x40000100, 0x42080100, 0x42080100, 0x02000100,
|
||||
0x42080000, 0x40000100, 0x00000000, 0x42000000,
|
||||
0x02080100, 0x02000000, 0x42000000, 0x00080100,
|
||||
0x00080000, 0x42000100, 0x00000100, 0x02000000,
|
||||
0x40000000, 0x02080000, 0x42000100, 0x40080100,
|
||||
0x02000100, 0x40000000, 0x42080000, 0x02080100,
|
||||
0x40080100, 0x00000100, 0x02000000, 0x42080000,
|
||||
0x42080100, 0x00080100, 0x42000000, 0x42080100,
|
||||
0x02080000, 0x00000000, 0x40080000, 0x42000000,
|
||||
0x00080100, 0x02000100, 0x40000100, 0x00080000,
|
||||
0x00000000, 0x40080000, 0x02080100, 0x40000100
|
||||
};
|
||||
private static int[] SP6 = {
|
||||
0x20000010, 0x20400000, 0x00004000, 0x20404010,
|
||||
0x20400000, 0x00000010, 0x20404010, 0x00400000,
|
||||
0x20004000, 0x00404010, 0x00400000, 0x20000010,
|
||||
0x00400010, 0x20004000, 0x20000000, 0x00004010,
|
||||
0x00000000, 0x00400010, 0x20004010, 0x00004000,
|
||||
0x00404000, 0x20004010, 0x00000010, 0x20400010,
|
||||
0x20400010, 0x00000000, 0x00404010, 0x20404000,
|
||||
0x00004010, 0x00404000, 0x20404000, 0x20000000,
|
||||
0x20004000, 0x00000010, 0x20400010, 0x00404000,
|
||||
0x20404010, 0x00400000, 0x00004010, 0x20000010,
|
||||
0x00400000, 0x20004000, 0x20000000, 0x00004010,
|
||||
0x20000010, 0x20404010, 0x00404000, 0x20400000,
|
||||
0x00404010, 0x20404000, 0x00000000, 0x20400010,
|
||||
0x00000010, 0x00004000, 0x20400000, 0x00404010,
|
||||
0x00004000, 0x00400010, 0x20004010, 0x00000000,
|
||||
0x20404000, 0x20000000, 0x00400010, 0x20004010
|
||||
};
|
||||
private static int[] SP7 = {
|
||||
0x00200000, 0x04200002, 0x04000802, 0x00000000,
|
||||
0x00000800, 0x04000802, 0x00200802, 0x04200800,
|
||||
0x04200802, 0x00200000, 0x00000000, 0x04000002,
|
||||
0x00000002, 0x04000000, 0x04200002, 0x00000802,
|
||||
0x04000800, 0x00200802, 0x00200002, 0x04000800,
|
||||
0x04000002, 0x04200000, 0x04200800, 0x00200002,
|
||||
0x04200000, 0x00000800, 0x00000802, 0x04200802,
|
||||
0x00200800, 0x00000002, 0x04000000, 0x00200800,
|
||||
0x04000000, 0x00200800, 0x00200000, 0x04000802,
|
||||
0x04000802, 0x04200002, 0x04200002, 0x00000002,
|
||||
0x00200002, 0x04000000, 0x04000800, 0x00200000,
|
||||
0x04200800, 0x00000802, 0x00200802, 0x04200800,
|
||||
0x00000802, 0x04000002, 0x04200802, 0x04200000,
|
||||
0x00200800, 0x00000000, 0x00000002, 0x04200802,
|
||||
0x00000000, 0x00200802, 0x04200000, 0x00000800,
|
||||
0x04000002, 0x04000800, 0x00000800, 0x00200002
|
||||
};
|
||||
private static int[] SP8 = {
|
||||
0x10001040, 0x00001000, 0x00040000, 0x10041040,
|
||||
0x10000000, 0x10001040, 0x00000040, 0x10000000,
|
||||
0x00040040, 0x10040000, 0x10041040, 0x00041000,
|
||||
0x10041000, 0x00041040, 0x00001000, 0x00000040,
|
||||
0x10040000, 0x10000040, 0x10001000, 0x00001040,
|
||||
0x00041000, 0x00040040, 0x10040040, 0x10041000,
|
||||
0x00001040, 0x00000000, 0x00000000, 0x10040040,
|
||||
0x10000040, 0x10001000, 0x00041040, 0x00040000,
|
||||
0x00041040, 0x00040000, 0x10041000, 0x00001000,
|
||||
0x00000040, 0x10040040, 0x00001000, 0x00041040,
|
||||
0x10001000, 0x00000040, 0x10000040, 0x10040000,
|
||||
0x10040040, 0x10000000, 0x00040000, 0x10001040,
|
||||
0x00000000, 0x10041040, 0x00040040, 0x10000040,
|
||||
0x10040000, 0x10001000, 0x10001040, 0x00000000,
|
||||
0x10041040, 0x00041000, 0x00041000, 0x00001040,
|
||||
0x00001040, 0x00040040, 0x10000000, 0x10041000
|
||||
};
|
||||
|
||||
// Routines taken from other parts of the Acme utilities.
|
||||
|
||||
/// Squash bytes down to ints.
|
||||
public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts, int outOff, int intLen )
|
||||
{
|
||||
for ( int i = 0; i < intLen; ++i )
|
||||
outInts[outOff + i] =
|
||||
( ( inBytes[inOff + i * 4 ] & 0xff ) << 24 ) |
|
||||
( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) |
|
||||
( ( inBytes[inOff + i * 4 + 2] & 0xff ) << 8 ) |
|
||||
( inBytes[inOff + i * 4 + 3] & 0xff );
|
||||
}
|
||||
|
||||
/// Spread ints into bytes.
|
||||
public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes, int outOff, int intLen )
|
||||
{
|
||||
for ( int i = 0; i < intLen; ++i )
|
||||
{
|
||||
outBytes[outOff + i * 4 ] = (byte) ( inInts[inOff + i] >>> 24 );
|
||||
outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 );
|
||||
outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>> 8 );
|
||||
outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
240
app/src/main/java/android/androidVNC/EnterTextDialog.java
Normal file
@@ -0,0 +1,240 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.*;
|
||||
import android.database.*;
|
||||
import android.database.sqlite.*;
|
||||
import android.os.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class EnterTextDialog extends Dialog {
|
||||
static final int NUMBER_SENT_SAVED = 100;
|
||||
static final int DELETED_ID = -10;
|
||||
|
||||
private VncCanvasActivity _canvasActivity;
|
||||
|
||||
private EditText _textEnterText;
|
||||
|
||||
private ArrayList<SentTextBean> _history;
|
||||
|
||||
private int _historyIndex;
|
||||
|
||||
private ImageButton _buttonNextEntry;
|
||||
private ImageButton _buttonPreviousEntry;
|
||||
|
||||
public EnterTextDialog(Context context) {
|
||||
super(context);
|
||||
setOwnerActivity((Activity)context);
|
||||
_canvasActivity = (VncCanvasActivity)context;
|
||||
_history = new ArrayList<SentTextBean>();
|
||||
}
|
||||
|
||||
private String saveText(boolean wasSent)
|
||||
{
|
||||
CharSequence cs = _textEnterText.getText();
|
||||
if (cs.length()==0)
|
||||
return "";
|
||||
String s = cs.toString();
|
||||
if (wasSent || _historyIndex>=_history.size() || ! s.equals(_history.get(_historyIndex).getSentText()))
|
||||
{
|
||||
SentTextBean added = new SentTextBean();
|
||||
added.setSentText(s);
|
||||
SQLiteDatabase db = _canvasActivity.database.getWritableDatabase();
|
||||
added.Gen_insert(db);
|
||||
_history.add(added);
|
||||
for (int i = 0; i < _historyIndex - NUMBER_SENT_SAVED; i++)
|
||||
{
|
||||
SentTextBean deleteCandidate = _history.get(i);
|
||||
if (deleteCandidate.get_Id() != DELETED_ID)
|
||||
{
|
||||
deleteCandidate.Gen_delete(db);
|
||||
deleteCandidate.set_Id(DELETED_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private void sendText(String s)
|
||||
{
|
||||
RfbProto rfb = _canvasActivity.vncCanvas.rfb;
|
||||
int l = s.length();
|
||||
for (int i = 0; i<l; i++)
|
||||
{
|
||||
char c = s.charAt(i);
|
||||
int meta = 0;
|
||||
int keysym = c;
|
||||
if (Character.isISOControl(c))
|
||||
{
|
||||
if (c=='\n')
|
||||
keysym = MetaKeyBean.keysByKeyCode.get(KeyEvent.KEYCODE_ENTER).keySym;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
rfb.writeKeyEvent(keysym, meta, true);
|
||||
rfb.writeKeyEvent(keysym, meta, false);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
// TODO: log this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onCreate(android.os.Bundle)
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.entertext);
|
||||
setTitle(R.string.enter_text_title);
|
||||
_textEnterText = (EditText)findViewById(R.id.textEnterText);
|
||||
_buttonNextEntry = (ImageButton)findViewById(R.id.buttonNextEntry);
|
||||
_buttonNextEntry.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.view.View.OnClickListener#onClick(android.view.View)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int oldSize = _history.size();
|
||||
if (_historyIndex < oldSize)
|
||||
{
|
||||
saveText(false);
|
||||
_historyIndex++;
|
||||
if (_history.size()>oldSize && _historyIndex==oldSize)
|
||||
_historyIndex++;
|
||||
if (_historyIndex < _history.size())
|
||||
{
|
||||
_textEnterText.setText(_history.get(_historyIndex).getSentText());
|
||||
}
|
||||
else
|
||||
{
|
||||
_textEnterText.setText("");
|
||||
}
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
});
|
||||
_buttonPreviousEntry = (ImageButton)findViewById(R.id.buttonPreviousEntry);
|
||||
_buttonPreviousEntry.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.view.View.OnClickListener#onClick(android.view.View)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (_historyIndex > 0)
|
||||
{
|
||||
saveText(false);
|
||||
_historyIndex--;
|
||||
_textEnterText.setText(_history.get(_historyIndex).getSentText());
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
});
|
||||
((Button)findViewById(R.id.buttonSendText)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.view.View.OnClickListener#onClick(android.view.View)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String s = saveText(true);
|
||||
sendText(s);
|
||||
_textEnterText.setText("");
|
||||
_historyIndex = _history.size();
|
||||
updateButtons();
|
||||
dismiss();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
((Button)findViewById(R.id.buttonSendWithoutSaving)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String s = _textEnterText.getText().toString();
|
||||
sendText(s);
|
||||
_textEnterText.setText("");
|
||||
_historyIndex = _history.size();
|
||||
updateButtons();
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
((ImageButton)findViewById(R.id.buttonTextDelete)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (_historyIndex < _history.size())
|
||||
{
|
||||
String s = _textEnterText.getText().toString();
|
||||
SentTextBean bean = _history.get(_historyIndex);
|
||||
if (s.equals(bean.getSentText()))
|
||||
{
|
||||
|
||||
bean.Gen_delete(_canvasActivity.database.getWritableDatabase());
|
||||
_history.remove(_historyIndex);
|
||||
if (_historyIndex > 0)
|
||||
{
|
||||
_historyIndex = _historyIndex - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
String s = "";
|
||||
if (_historyIndex < _history.size())
|
||||
{
|
||||
s = _history.get(_historyIndex).getSentText();
|
||||
}
|
||||
_textEnterText.setText(s);
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
});
|
||||
Cursor readInOrder = _canvasActivity.database.getReadableDatabase().rawQuery(
|
||||
"select * from " + SentTextBean.GEN_TABLE_NAME + " ORDER BY _id", null);
|
||||
try
|
||||
{
|
||||
SentTextBean.Gen_populateFromCursor(readInOrder, _history, SentTextBean.GEN_NEW);
|
||||
}
|
||||
finally
|
||||
{
|
||||
readInOrder.close();
|
||||
}
|
||||
_historyIndex = _history.size();
|
||||
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
private void updateButtons()
|
||||
{
|
||||
_buttonPreviousEntry.setEnabled(_historyIndex > 0);
|
||||
_buttonNextEntry.setEnabled(_historyIndex <_history.size());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onStart()
|
||||
*/
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
_textEnterText.requestFocus();
|
||||
}
|
||||
}
|
||||
56
app/src/main/java/android/androidVNC/FitToScreenScaling.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.widget.ImageView.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
class FitToScreenScaling extends AbstractScaling {
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param scaleType
|
||||
*/
|
||||
FitToScreenScaling() {
|
||||
super(R.id.itemFitToScreen, ScaleType.FIT_CENTER);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#isAbleToPan()
|
||||
*/
|
||||
@Override
|
||||
boolean isAbleToPan() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#isValidInputMode(int)
|
||||
*/
|
||||
@Override
|
||||
boolean isValidInputMode(int mode) {
|
||||
return mode == R.id.itemInputFitToScreen;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#getDefaultHandlerId()
|
||||
*/
|
||||
@Override
|
||||
int getDefaultHandlerId() {
|
||||
return R.id.itemInputFitToScreen;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#setCanvasScaleType(android.androidVNC.VncCanvas)
|
||||
*/
|
||||
@Override
|
||||
void setScaleTypeForActivity(VncCanvasActivity activity) {
|
||||
super.setScaleTypeForActivity(activity);
|
||||
activity.vncCanvas.absoluteXPosition = activity.vncCanvas.absoluteYPosition = 0;
|
||||
activity.vncCanvas.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
202
app/src/main/java/android/androidVNC/FullBufferBitmapData.java
Normal file
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.widget.ImageView;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class FullBufferBitmapData extends AbstractBitmapData {
|
||||
|
||||
int xoffset;
|
||||
int yoffset;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class Drawable extends AbstractBitmapDrawable {
|
||||
|
||||
/**
|
||||
* @param data
|
||||
*/
|
||||
public Drawable(AbstractBitmapData data) {
|
||||
super(data);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.graphics.drawable.DrawableContainer#draw(android.graphics.Canvas)
|
||||
*/
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (vncCanvas.getScaleType() == ImageView.ScaleType.FIT_CENTER)
|
||||
{
|
||||
canvas.drawBitmap(data.bitmapPixels, 0, data.framebufferwidth, xoffset, yoffset, framebufferwidth, framebufferheight, false, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
float scale = vncCanvas.getScale();
|
||||
int xo = xoffset < 0 ? 0 : xoffset;
|
||||
int yo = yoffset < 0 ? 0 : yoffset;
|
||||
/*
|
||||
if (scale == 1 || scale <= 0)
|
||||
{
|
||||
*/
|
||||
int drawWidth = vncCanvas.getVisibleWidth();
|
||||
if (drawWidth + xo > data.framebufferwidth)
|
||||
drawWidth = data.framebufferwidth - xo;
|
||||
int drawHeight = vncCanvas.getVisibleHeight();
|
||||
if (drawHeight + yo > data.framebufferheight)
|
||||
drawHeight = data.framebufferheight - yo;
|
||||
canvas.drawBitmap(data.bitmapPixels, offset(xo, yo), data.framebufferwidth, xo, yo, drawWidth, drawHeight, false, null);
|
||||
/*
|
||||
}
|
||||
else
|
||||
{
|
||||
int scalewidth = (int)(vncCanvas.getVisibleWidth() / scale + 1);
|
||||
if (scalewidth + xo > data.framebufferwidth)
|
||||
scalewidth = data.framebufferwidth - xo;
|
||||
int scaleheight = (int)(vncCanvas.getVisibleHeight() / scale + 1);
|
||||
if (scaleheight + yo > data.framebufferheight)
|
||||
scaleheight = data.framebufferheight - yo;
|
||||
canvas.drawBitmap(data.bitmapPixels, offset(xo, yo), data.framebufferwidth, xo, yo, scalewidth, scaleheight, false, null);
|
||||
}
|
||||
*/
|
||||
}
|
||||
if(data.vncCanvas.connection.getUseLocalCursor())
|
||||
{
|
||||
setCursorRect(data.vncCanvas.mouseX, data.vncCanvas.mouseY);
|
||||
clipRect.set(cursorRect);
|
||||
if (canvas.clipRect(cursorRect))
|
||||
{
|
||||
drawCursor(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply this times total number of pixels to get estimate of process size with all buffers plus
|
||||
* safety factor
|
||||
*/
|
||||
static final int CAPACITY_MULTIPLIER = 7;
|
||||
|
||||
/**
|
||||
* @param p
|
||||
* @param c
|
||||
*/
|
||||
public FullBufferBitmapData(RfbProto p, VncCanvas c, int capacity) {
|
||||
super(p, c);
|
||||
framebufferwidth=rfb.framebufferWidth;
|
||||
framebufferheight=rfb.framebufferHeight;
|
||||
bitmapwidth=framebufferwidth;
|
||||
bitmapheight=framebufferheight;
|
||||
android.util.Log.i("FBBM", "bitmapsize = ("+bitmapwidth+","+bitmapheight+")");
|
||||
bitmapPixels = new int[framebufferwidth * framebufferheight];
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#copyRect(android.graphics.Rect, android.graphics.Rect, android.graphics.Paint)
|
||||
*/
|
||||
@Override
|
||||
void copyRect(Rect src, Rect dest, Paint paint) {
|
||||
// TODO copy rect working?
|
||||
throw new RuntimeException( "copyrect Not implemented");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#createDrawable()
|
||||
*/
|
||||
@Override
|
||||
AbstractBitmapDrawable createDrawable() {
|
||||
return new Drawable(this);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#drawRect(int, int, int, int, android.graphics.Paint)
|
||||
*/
|
||||
@Override
|
||||
void drawRect(int x, int y, int w, int h, Paint paint) {
|
||||
int color = paint.getColor();
|
||||
int offset = offset(x,y);
|
||||
if (w > 10)
|
||||
{
|
||||
for (int j = 0; j < h; j++, offset += framebufferwidth)
|
||||
{
|
||||
Arrays.fill(bitmapPixels, offset, offset + w, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < h; j++, offset += framebufferwidth - w)
|
||||
{
|
||||
for (int k = 0; k < w; k++, offset++)
|
||||
{
|
||||
bitmapPixels[offset] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#offset(int, int)
|
||||
*/
|
||||
@Override
|
||||
int offset(int x, int y) {
|
||||
return x + y * framebufferwidth;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#scrollChanged(int, int)
|
||||
*/
|
||||
@Override
|
||||
void scrollChanged(int newx, int newy) {
|
||||
xoffset = newx;
|
||||
yoffset = newy;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#syncScroll()
|
||||
*/
|
||||
@Override
|
||||
void syncScroll() {
|
||||
// Don't need to do anything here
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#updateBitmap(int, int, int, int)
|
||||
*/
|
||||
@Override
|
||||
void updateBitmap(int x, int y, int w, int h) {
|
||||
// Don't need to do anything here
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#validDraw(int, int, int, int)
|
||||
*/
|
||||
@Override
|
||||
boolean validDraw(int x, int y, int w, int h) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#writeFullUpdateRequest(boolean)
|
||||
*/
|
||||
@Override
|
||||
void writeFullUpdateRequest(boolean incremental) throws IOException {
|
||||
rfb.writeFramebufferUpdateRequest(0, 0, framebufferwidth, framebufferheight, incremental);
|
||||
}
|
||||
|
||||
}
|
||||
62
app/src/main/java/android/androidVNC/IConnectionBean.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import com.antlersoft.android.db.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
@TableInterface(ImplementingClassName="AbstractConnectionBean",TableName="CONNECTION_BEAN")
|
||||
interface IConnectionBean {
|
||||
@FieldAccessor
|
||||
long get_Id();
|
||||
@FieldAccessor
|
||||
String getNickname();
|
||||
@FieldAccessor
|
||||
String getAddress();
|
||||
@FieldAccessor
|
||||
int getPort();
|
||||
@FieldAccessor
|
||||
String getPassword();
|
||||
@FieldAccessor
|
||||
String getColorModel();
|
||||
/**
|
||||
* Records bitmap data implementation selection. 0 for auto, 1 for force full bitmap, 2 for force tiled
|
||||
* <p>
|
||||
* For historical reasons, this is named as if it were just a boolean selection for auto and force full.
|
||||
* @return 0 for auto, 1 for force full bitmap, 2 for forced tiled
|
||||
*/
|
||||
@FieldAccessor
|
||||
long getForceFull();
|
||||
@FieldAccessor
|
||||
String getRepeaterId();
|
||||
@FieldAccessor
|
||||
String getInputMode();
|
||||
@FieldAccessor(Name="SCALEMODE")
|
||||
String getScaleModeAsString();
|
||||
@FieldAccessor
|
||||
boolean getUseLocalCursor();
|
||||
@FieldAccessor
|
||||
boolean getKeepPassword();
|
||||
@FieldAccessor
|
||||
boolean getFollowMouse();
|
||||
@FieldAccessor
|
||||
boolean getUseRepeater();
|
||||
@FieldAccessor
|
||||
long getMetaListId();
|
||||
@FieldAccessor(Name="LAST_META_KEY_ID")
|
||||
long getLastMetaKeyId();
|
||||
@FieldAccessor(DefaultValue="false")
|
||||
boolean getFollowPan();
|
||||
@FieldAccessor
|
||||
String getUserName();
|
||||
@FieldAccessor
|
||||
String getSecureConnectionType();
|
||||
@FieldAccessor(DefaultValue="true")
|
||||
boolean getShowZoomButtons();
|
||||
@FieldAccessor(Name="DOUBLE_TAP_ACTION")
|
||||
String getDoubleTapActionAsString();
|
||||
}
|
||||
31
app/src/main/java/android/androidVNC/IMetaKey.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import com.antlersoft.android.db.FieldAccessor;
|
||||
import com.antlersoft.android.db.TableInterface;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
@TableInterface(TableName="META_KEY",ImplementingClassName="AbstractMetaKeyBean")
|
||||
public interface IMetaKey {
|
||||
@FieldAccessor
|
||||
long get_Id();
|
||||
@FieldAccessor
|
||||
long getMetaListId();
|
||||
@FieldAccessor
|
||||
String getKeyDesc();
|
||||
@FieldAccessor
|
||||
int getMetaFlags();
|
||||
@FieldAccessor
|
||||
boolean isMouseClick();
|
||||
@FieldAccessor
|
||||
int getMouseButtons();
|
||||
@FieldAccessor
|
||||
int getKeySym();
|
||||
@FieldAccessor
|
||||
String getShortcut();
|
||||
}
|
||||
19
app/src/main/java/android/androidVNC/IMetaList.java
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import com.antlersoft.android.db.FieldAccessor;
|
||||
import com.antlersoft.android.db.TableInterface;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
@TableInterface(TableName="META_LIST",ImplementingIsAbstract=false,ImplementingClassName="MetaList")
|
||||
public interface IMetaList {
|
||||
@FieldAccessor
|
||||
long get_Id();
|
||||
@FieldAccessor
|
||||
String getName();
|
||||
}
|
||||
22
app/src/main/java/android/androidVNC/IMostRecentBean.java
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import com.antlersoft.android.db.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
@TableInterface(TableName="MOST_RECENT",ImplementingIsAbstract=false,ImplementingClassName="MostRecentBean")
|
||||
public interface IMostRecentBean {
|
||||
@FieldAccessor
|
||||
long get_Id();
|
||||
@FieldAccessor(Name="CONNECTION_ID")
|
||||
long getConnectionId();
|
||||
@FieldAccessor(Name="SHOW_SPLASH_VERSION")
|
||||
long getShowSplashVersion();
|
||||
@FieldAccessor(Name="TEXT_INDEX")
|
||||
long getTextIndex();
|
||||
}
|
||||
21
app/src/main/java/android/androidVNC/ISentText.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import com.antlersoft.android.db.FieldAccessor;
|
||||
import com.antlersoft.android.db.TableInterface;
|
||||
/**
|
||||
* Interface specification for table storing sent text; the last N text items sent are stored in a table
|
||||
* and will be recalled on demand
|
||||
*
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
@TableInterface(TableName="SENT_TEXT",ImplementingIsAbstract=false,ImplementingClassName="SentTextBean")
|
||||
public interface ISentText {
|
||||
@FieldAccessor
|
||||
long get_Id();
|
||||
@FieldAccessor
|
||||
String getSentText();
|
||||
}
|
||||
126
app/src/main/java/android/androidVNC/ImportExportDialog.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.app.*;
|
||||
import android.os.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import com.antlersoft.android.bc.*;
|
||||
import com.antlersoft.android.contentxml.*;
|
||||
import com.antlersoft.android.contentxml.SqliteElement.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
import org.xml.sax.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class ImportExportDialog extends Dialog {
|
||||
|
||||
private androidVNC _configurationDialog;
|
||||
private EditText _textLoadUrl;
|
||||
private EditText _textSaveUrl;
|
||||
|
||||
|
||||
/**
|
||||
* @param context
|
||||
*/
|
||||
public ImportExportDialog(androidVNC context) {
|
||||
super(context);
|
||||
setOwnerActivity((Activity)context);
|
||||
_configurationDialog = context;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onCreate(android.os.Bundle)
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.importexport);
|
||||
setTitle(R.string.import_export_settings);
|
||||
_textLoadUrl = (EditText)findViewById(R.id.textImportUrl);
|
||||
_textSaveUrl = (EditText)findViewById(R.id.textExportPath);
|
||||
|
||||
File f = BCFactory.getInstance().getStorageContext().getExternalStorageDir(_configurationDialog, null);
|
||||
// Sdcard not mounted; nothing else to do
|
||||
if (f == null)
|
||||
return;
|
||||
|
||||
f = new File(f, "vnc_settings.xml");
|
||||
|
||||
_textSaveUrl.setText(f.getAbsolutePath());
|
||||
try {
|
||||
_textLoadUrl.setText(f.toURL().toString());
|
||||
} catch (MalformedURLException e) {
|
||||
// Do nothing; default value not set
|
||||
}
|
||||
|
||||
Button export = (Button)findViewById(R.id.buttonExport);
|
||||
export.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
File f = new File(_textSaveUrl.getText().toString());
|
||||
Writer writer = new OutputStreamWriter(new FileOutputStream(f, false));
|
||||
SqliteElement.exportDbAsXmlToStream(_configurationDialog.getDatabaseHelper().getReadableDatabase(), writer);
|
||||
writer.close();
|
||||
dismiss();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
errorNotify("I/O Exception exporting config", ioe);
|
||||
} catch (SAXException e) {
|
||||
errorNotify("XML Exception exporting config", e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
((Button)findViewById(R.id.buttonImport)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
try
|
||||
{
|
||||
URL url = new URL(_textLoadUrl.getText().toString());
|
||||
URLConnection connection = url.openConnection();
|
||||
connection.connect();
|
||||
Reader reader = new InputStreamReader(connection.getInputStream());
|
||||
SqliteElement.importXmlStreamToDb(
|
||||
_configurationDialog.getDatabaseHelper().getWritableDatabase(),
|
||||
reader,
|
||||
ReplaceStrategy.REPLACE_EXISTING);
|
||||
dismiss();
|
||||
_configurationDialog.arriveOnPage();
|
||||
}
|
||||
catch (MalformedURLException mfe)
|
||||
{
|
||||
errorNotify("Improper URL given: " + _textLoadUrl.getText(), mfe);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
errorNotify("I/O error reading configuration", ioe);
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
errorNotify("XML or format error reading configuration", e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void errorNotify(String msg, Throwable t)
|
||||
{
|
||||
Log.i("android.androidVNC.ImportExportDialog", msg, t);
|
||||
Utils.showErrorMessage(this.getContext(), msg + ":" + t.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
155
app/src/main/java/android/androidVNC/InStream.java
Normal file
@@ -0,0 +1,155 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// rdr::InStream marshalls data from a buffer stored in RDR (RFB Data
|
||||
// Representation).
|
||||
//
|
||||
package android.androidVNC;
|
||||
|
||||
|
||||
abstract public class InStream {
|
||||
|
||||
// check() ensures there is buffer data for at least one item of size
|
||||
// itemSize bytes. Returns the number of items in the buffer (up to a
|
||||
// maximum of nItems).
|
||||
|
||||
public final int check(int itemSize, int nItems) throws Exception {
|
||||
if (ptr + itemSize * nItems > end) {
|
||||
if (ptr + itemSize > end)
|
||||
return overrun(itemSize, nItems);
|
||||
|
||||
nItems = (end - ptr) / itemSize;
|
||||
}
|
||||
return nItems;
|
||||
}
|
||||
|
||||
public final void check(int itemSize) throws Exception {
|
||||
if (ptr + itemSize > end)
|
||||
overrun(itemSize, 1);
|
||||
}
|
||||
|
||||
// readU/SN() methods read unsigned and signed N-bit integers.
|
||||
|
||||
public final int readS8() throws Exception {
|
||||
check(1); return b[ptr++];
|
||||
}
|
||||
|
||||
public final int readS16() throws Exception {
|
||||
check(2); int b0 = b[ptr++];
|
||||
int b1 = b[ptr++] & 0xff; return b0 << 8 | b1;
|
||||
}
|
||||
|
||||
public final int readS32() throws Exception {
|
||||
check(4); int b0 = b[ptr++];
|
||||
int b1 = b[ptr++] & 0xff;
|
||||
int b2 = b[ptr++] & 0xff;
|
||||
int b3 = b[ptr++] & 0xff;
|
||||
return b0 << 24 | b1 << 16 | b2 << 8 | b3;
|
||||
}
|
||||
|
||||
public final int readU8() throws Exception {
|
||||
return readS8() & 0xff;
|
||||
}
|
||||
|
||||
public final int readU16() throws Exception {
|
||||
return readS16() & 0xffff;
|
||||
}
|
||||
|
||||
public final int readU32() throws Exception {
|
||||
return readS32() & 0xffffffff;
|
||||
}
|
||||
|
||||
public final void skip(int bytes) throws Exception {
|
||||
while (bytes > 0) {
|
||||
int n = check(1, bytes);
|
||||
ptr += n;
|
||||
bytes -= n;
|
||||
}
|
||||
}
|
||||
|
||||
// readBytes() reads an exact number of bytes into an array at an offset.
|
||||
|
||||
public void readBytes(byte[] data, int offset, int length) throws Exception {
|
||||
int offsetEnd = offset + length;
|
||||
while (offset < offsetEnd) {
|
||||
int n = check(1, offsetEnd - offset);
|
||||
System.arraycopy(b, ptr, data, offset, n);
|
||||
ptr += n;
|
||||
offset += n;
|
||||
}
|
||||
}
|
||||
|
||||
// readOpaqueN() reads a quantity "without byte-swapping". Because java has
|
||||
// no byte-ordering, we just use big-endian.
|
||||
|
||||
public final int readOpaque8() throws Exception {
|
||||
return readU8();
|
||||
}
|
||||
|
||||
public final int readOpaque16() throws Exception {
|
||||
return readU16();
|
||||
}
|
||||
|
||||
public final int readOpaque32() throws Exception {
|
||||
return readU32();
|
||||
}
|
||||
|
||||
public final int readOpaque24A() throws Exception {
|
||||
check(3); int b0 = b[ptr++];
|
||||
int b1 = b[ptr++]; int b2 = b[ptr++];
|
||||
return b0 << 24 | b1 << 16 | b2 << 8;
|
||||
}
|
||||
|
||||
public final int readOpaque24B() throws Exception {
|
||||
check(3); int b0 = b[ptr++];
|
||||
int b1 = b[ptr++]; int b2 = b[ptr++];
|
||||
return b0 << 16 | b1 << 8 | b2;
|
||||
}
|
||||
|
||||
// pos() returns the position in the stream.
|
||||
|
||||
abstract public int pos();
|
||||
|
||||
// bytesAvailable() returns true if at least one byte can be read from the
|
||||
// stream without blocking. i.e. if false is returned then readU8() would
|
||||
// block.
|
||||
|
||||
public boolean bytesAvailable() { return end != ptr; }
|
||||
|
||||
// getbuf(), getptr(), getend() and setptr() are "dirty" methods which allow
|
||||
// you to manipulate the buffer directly. This is useful for a stream which
|
||||
// is a wrapper around an underlying stream.
|
||||
|
||||
public final byte[] getbuf() { return b; }
|
||||
public final int getptr() { return ptr; }
|
||||
public final int getend() { return end; }
|
||||
public final void setptr(int p) { ptr = p; }
|
||||
|
||||
// overrun() is implemented by a derived class to cope with buffer overrun.
|
||||
// It ensures there are at least itemSize bytes of buffer data. Returns
|
||||
// the number of items in the buffer (up to a maximum of nItems). itemSize
|
||||
// is supposed to be "small" (a few bytes).
|
||||
|
||||
abstract protected int overrun(int itemSize, int nItems) throws Exception;
|
||||
|
||||
protected InStream() {}
|
||||
protected byte[] b;
|
||||
protected int ptr;
|
||||
protected int end;
|
||||
}
|
||||
149
app/src/main/java/android/androidVNC/IntroTextDialog.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.pm.*;
|
||||
import android.database.sqlite.*;
|
||||
import android.os.*;
|
||||
import android.text.*;
|
||||
import android.text.method.*;
|
||||
import android.view.*;
|
||||
import android.view.MenuItem.*;
|
||||
import android.widget.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class IntroTextDialog extends Dialog {
|
||||
|
||||
private PackageInfo packageInfo;
|
||||
private VncDatabase database;
|
||||
|
||||
static IntroTextDialog dialog;
|
||||
|
||||
static void showIntroTextIfNecessary(Activity context, VncDatabase database)
|
||||
{
|
||||
PackageInfo pi;
|
||||
try
|
||||
{
|
||||
pi = context.getPackageManager().getPackageInfo("android.androidVNC", 0);
|
||||
}
|
||||
catch (PackageManager.NameNotFoundException nnfe)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MostRecentBean mr = androidVNC.getMostRecent(database.getReadableDatabase());
|
||||
if (mr == null || mr.getShowSplashVersion() != pi.versionCode)
|
||||
{
|
||||
if (dialog == null)
|
||||
{
|
||||
dialog = new IntroTextDialog(context, pi, database);
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context -- Containing dialog
|
||||
*/
|
||||
private IntroTextDialog(Activity context, PackageInfo pi, VncDatabase database) {
|
||||
super(context);
|
||||
setOwnerActivity(context);
|
||||
packageInfo = pi;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onCreate(android.os.Bundle)
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.intro_dialog);
|
||||
StringBuilder sb = new StringBuilder(getContext().getResources().getString(R.string.intro_title));
|
||||
sb.append(" ");
|
||||
sb.append(packageInfo.versionName);
|
||||
setTitle(sb);
|
||||
sb.delete(0, sb.length());
|
||||
sb.append(getContext().getResources().getString(R.string.intro_text));
|
||||
sb.append(packageInfo.versionName);
|
||||
sb.append(getContext().getResources().getString(R.string.intro_version_text));
|
||||
TextView introTextView = (TextView)findViewById(R.id.textIntroText);
|
||||
introTextView.setText(Html.fromHtml(sb.toString()));
|
||||
introTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
((Button)findViewById(R.id.buttonCloseIntro)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.view.View.OnClickListener#onClick(android.view.View)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
|
||||
});
|
||||
((Button)findViewById(R.id.buttonCloseIntroDontShow)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.view.View.OnClickListener#onClick(android.view.View)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dontShowAgain();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onCreateOptionsMenu(android.view.Menu)
|
||||
*/
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
getOwnerActivity().getMenuInflater().inflate(R.menu.intro_dialog_menu,menu);
|
||||
menu.findItem(R.id.itemOpenDoc).setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
Utils.showDocumentation(getOwnerActivity());
|
||||
dismiss();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
menu.findItem(R.id.itemClose).setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
dismiss();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
menu.findItem(R.id.itemDontShowAgain).setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
dontShowAgain();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
private void dontShowAgain()
|
||||
{
|
||||
SQLiteDatabase db = database.getWritableDatabase();
|
||||
MostRecentBean mostRecent = androidVNC.getMostRecent(db);
|
||||
if (mostRecent != null)
|
||||
{
|
||||
mostRecent.setShowSplashVersion(packageInfo.versionCode);
|
||||
mostRecent.Gen_update(db);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
318
app/src/main/java/android/androidVNC/LargeBitmapData.java
Normal file
@@ -0,0 +1,318 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.antlersoft.android.drawing.OverlappingCopy;
|
||||
import com.antlersoft.android.drawing.RectList;
|
||||
import com.antlersoft.util.ObjectPool;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class LargeBitmapData extends AbstractBitmapData {
|
||||
|
||||
/**
|
||||
* Multiply this times total number of pixels to get estimate of process size with all buffers plus
|
||||
* safety factor
|
||||
*/
|
||||
static final int CAPACITY_MULTIPLIER = 21;
|
||||
|
||||
int xoffset;
|
||||
int yoffset;
|
||||
int scrolledToX;
|
||||
int scrolledToY;
|
||||
private Rect bitmapRect;
|
||||
private Paint defaultPaint;
|
||||
private RectList invalidList;
|
||||
private RectList pendingList;
|
||||
|
||||
/**
|
||||
* Pool of temporary rectangle objects. Need to synchronize externally access from
|
||||
* multiple threads.
|
||||
*/
|
||||
private static ObjectPool<Rect> rectPool = new ObjectPool<Rect>() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.util.ObjectPool#itemForPool()
|
||||
*/
|
||||
@Override
|
||||
protected Rect itemForPool() {
|
||||
return new Rect();
|
||||
}
|
||||
};
|
||||
|
||||
class LargeBitmapDrawable extends AbstractBitmapDrawable
|
||||
{
|
||||
LargeBitmapDrawable()
|
||||
{
|
||||
super(LargeBitmapData.this);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see android.graphics.drawable.DrawableContainer#draw(android.graphics.Canvas)
|
||||
*/
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
//android.util.Log.i("LBM", "Drawing "+xoffset+" "+yoffset);
|
||||
int xoff, yoff;
|
||||
synchronized ( LargeBitmapData.this )
|
||||
{
|
||||
xoff=xoffset;
|
||||
yoff=yoffset;
|
||||
}
|
||||
draw(canvas, xoff, yoff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param p Protocol implementation
|
||||
* @param c View that will display screen
|
||||
* @param displayWidth
|
||||
* @param displayHeight
|
||||
* @param capacity Max process heap size in bytes
|
||||
*/
|
||||
LargeBitmapData(RfbProto p, VncCanvas c, int displayWidth, int displayHeight, int capacity)
|
||||
{
|
||||
super(p,c);
|
||||
double scaleMultiplier = Math.sqrt((double)(capacity * 1024 * 1024) / (double)(CAPACITY_MULTIPLIER * framebufferwidth * framebufferheight));
|
||||
if (scaleMultiplier > 1)
|
||||
scaleMultiplier = 1;
|
||||
bitmapwidth=(int)((double)framebufferwidth * scaleMultiplier);
|
||||
if (bitmapwidth < displayWidth)
|
||||
bitmapwidth = displayWidth;
|
||||
bitmapheight=(int)((double)framebufferheight * scaleMultiplier);
|
||||
if (bitmapheight < displayHeight)
|
||||
bitmapheight = displayHeight;
|
||||
android.util.Log.i("LBM", "bitmapsize = ("+bitmapwidth+","+bitmapheight+")");
|
||||
mbitmap = Bitmap.createBitmap(bitmapwidth, bitmapheight, Bitmap.Config.RGB_565);
|
||||
memGraphics = new Canvas(mbitmap);
|
||||
bitmapPixels = new int[bitmapwidth * bitmapheight];
|
||||
invalidList = new RectList(rectPool);
|
||||
pendingList = new RectList(rectPool);
|
||||
bitmapRect=new Rect(0,0,bitmapwidth,bitmapheight);
|
||||
defaultPaint = new Paint();
|
||||
}
|
||||
|
||||
@Override
|
||||
AbstractBitmapDrawable createDrawable()
|
||||
{
|
||||
return new LargeBitmapDrawable();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#copyRect(android.graphics.Rect, android.graphics.Rect, android.graphics.Paint)
|
||||
*/
|
||||
@Override
|
||||
void copyRect(Rect src, Rect dest, Paint paint) {
|
||||
// TODO copy rect working?
|
||||
throw new RuntimeException( "copyrect Not implemented");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#drawRect(int, int, int, int, android.graphics.Paint)
|
||||
*/
|
||||
@Override
|
||||
void drawRect(int x, int y, int w, int h, Paint paint) {
|
||||
x-=xoffset;
|
||||
y-=yoffset;
|
||||
memGraphics.drawRect(x, y, x+w, y+h, paint);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#offset(int, int)
|
||||
*/
|
||||
@Override
|
||||
int offset(int x, int y) {
|
||||
return (y - yoffset) * bitmapwidth + x - xoffset;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#scrollChanged(int, int)
|
||||
*/
|
||||
@Override
|
||||
synchronized void scrollChanged(int newx, int newy) {
|
||||
//android.util.Log.i("LBM","scroll "+newx+" "+newy);
|
||||
int newScrolledToX = scrolledToX;
|
||||
int newScrolledToY = scrolledToY;
|
||||
int visibleWidth = vncCanvas.getVisibleWidth();
|
||||
int visibleHeight = vncCanvas.getVisibleHeight();
|
||||
if (newx - xoffset < 0 )
|
||||
{
|
||||
newScrolledToX = newx + visibleWidth / 2 - bitmapwidth / 2;
|
||||
if (newScrolledToX < 0)
|
||||
newScrolledToX = 0;
|
||||
}
|
||||
else if (newx - xoffset + visibleWidth > bitmapwidth)
|
||||
{
|
||||
newScrolledToX = newx + visibleWidth / 2 - bitmapwidth / 2;
|
||||
if (newScrolledToX + bitmapwidth > framebufferwidth)
|
||||
newScrolledToX = framebufferwidth - bitmapwidth;
|
||||
}
|
||||
if (newy - yoffset < 0 )
|
||||
{
|
||||
newScrolledToY = newy + visibleHeight / 2 - bitmapheight / 2;
|
||||
if (newScrolledToY < 0)
|
||||
newScrolledToY = 0;
|
||||
}
|
||||
else if (newy - yoffset + visibleHeight > bitmapheight)
|
||||
{
|
||||
newScrolledToY = newy + visibleHeight / 2 - bitmapheight / 2;
|
||||
if (newScrolledToY + bitmapheight > framebufferheight)
|
||||
newScrolledToY = framebufferheight - bitmapheight;
|
||||
}
|
||||
if (newScrolledToX != scrolledToX || newScrolledToY != scrolledToY)
|
||||
{
|
||||
scrolledToX = newScrolledToX;
|
||||
scrolledToY = newScrolledToY;
|
||||
if ( waitingForInput)
|
||||
syncScroll();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#updateBitmap(int, int, int, int)
|
||||
*/
|
||||
@Override
|
||||
void updateBitmap(int x, int y, int w, int h) {
|
||||
mbitmap.setPixels(bitmapPixels, offset(x,y), bitmapwidth, x-xoffset, y-yoffset, w, h);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#validDraw(int, int, int, int)
|
||||
*/
|
||||
@Override
|
||||
synchronized boolean validDraw(int x, int y, int w, int h) {
|
||||
//android.util.Log.i("LBM", "Validate Drawing "+x+" "+y+" "+w+" "+h+" "+xoffset+" "+yoffset+" "+(x-xoffset>=0 && x-xoffset+w<=bitmapwidth && y-yoffset>=0 && y-yoffset+h<=bitmapheight));
|
||||
boolean result = x-xoffset>=0 && x-xoffset+w<=bitmapwidth && y-yoffset>=0 && y-yoffset+h<=bitmapheight;
|
||||
ObjectPool.Entry<Rect> entry = rectPool.reserve();
|
||||
Rect r = entry.get();
|
||||
r.set(x, y, x+w, y+h);
|
||||
pendingList.subtract(r);
|
||||
if ( ! result)
|
||||
{
|
||||
invalidList.add(r);
|
||||
}
|
||||
else
|
||||
invalidList.subtract(r);
|
||||
rectPool.release(entry);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#writeFullUpdateRequest(boolean)
|
||||
*/
|
||||
@Override
|
||||
synchronized void writeFullUpdateRequest(boolean incremental) throws IOException {
|
||||
if (! incremental) {
|
||||
ObjectPool.Entry<Rect> entry = rectPool.reserve();
|
||||
Rect r = entry.get();
|
||||
r.left=xoffset;
|
||||
r.top=yoffset;
|
||||
r.right=xoffset + bitmapwidth;
|
||||
r.bottom=yoffset + bitmapheight;
|
||||
pendingList.add(r);
|
||||
invalidList.add(r);
|
||||
rectPool.release(entry);
|
||||
}
|
||||
rfb.writeFramebufferUpdateRequest(xoffset, yoffset, bitmapwidth, bitmapheight, incremental);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractBitmapData#syncScroll()
|
||||
*/
|
||||
@Override
|
||||
synchronized void syncScroll() {
|
||||
|
||||
int deltaX = xoffset - scrolledToX;
|
||||
int deltaY = yoffset - scrolledToY;
|
||||
xoffset=scrolledToX;
|
||||
yoffset=scrolledToY;
|
||||
bitmapRect.top=scrolledToY;
|
||||
bitmapRect.bottom=scrolledToY+bitmapheight;
|
||||
bitmapRect.left=scrolledToX;
|
||||
bitmapRect.right=scrolledToX+bitmapwidth;
|
||||
invalidList.intersect(bitmapRect);
|
||||
if ( deltaX != 0 || deltaY != 0)
|
||||
{
|
||||
boolean didOverlapping = false;
|
||||
if (Math.abs(deltaX) < bitmapwidth && Math.abs(deltaY) < bitmapheight) {
|
||||
ObjectPool.Entry<Rect> sourceEntry = rectPool.reserve();
|
||||
ObjectPool.Entry<Rect> addedEntry = rectPool.reserve();
|
||||
try
|
||||
{
|
||||
Rect added = addedEntry.get();
|
||||
Rect sourceRect = sourceEntry.get();
|
||||
sourceRect.set(deltaX<0 ? -deltaX : 0,
|
||||
deltaY<0 ? -deltaY : 0,
|
||||
deltaX<0 ? bitmapwidth : bitmapwidth - deltaX,
|
||||
deltaY < 0 ? bitmapheight : bitmapheight - deltaY);
|
||||
if (! invalidList.testIntersect(sourceRect)) {
|
||||
didOverlapping = true;
|
||||
OverlappingCopy.Copy(mbitmap, memGraphics, defaultPaint, sourceRect, deltaX + sourceRect.left, deltaY + sourceRect.top, rectPool);
|
||||
// Write request for side pixels
|
||||
if (deltaX != 0) {
|
||||
added.left = deltaX < 0 ? bitmapRect.right + deltaX : bitmapRect.left;
|
||||
added.right = added.left + Math.abs(deltaX);
|
||||
added.top = bitmapRect.top;
|
||||
added.bottom = bitmapRect.bottom;
|
||||
invalidList.add(added);
|
||||
}
|
||||
if (deltaY != 0) {
|
||||
added.left = deltaX < 0 ? bitmapRect.left : bitmapRect.left + deltaX;
|
||||
added.top = deltaY < 0 ? bitmapRect.bottom + deltaY : bitmapRect.top;
|
||||
added.right = added.left + bitmapwidth - Math.abs(deltaX);
|
||||
added.bottom = added.top + Math.abs(deltaY);
|
||||
invalidList.add(added);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
rectPool.release(addedEntry);
|
||||
rectPool.release(sourceEntry);
|
||||
}
|
||||
}
|
||||
if (! didOverlapping)
|
||||
{
|
||||
try
|
||||
{
|
||||
//android.util.Log.i("LBM","update req "+xoffset+" "+yoffset);
|
||||
mbitmap.eraseColor(Color.GREEN);
|
||||
writeFullUpdateRequest(false);
|
||||
}
|
||||
catch ( IOException ioe)
|
||||
{
|
||||
// TODO log this
|
||||
}
|
||||
}
|
||||
}
|
||||
int size = pendingList.getSize();
|
||||
for (int i=0; i<size; i++) {
|
||||
invalidList.subtract(pendingList.get(i));
|
||||
}
|
||||
size = invalidList.getSize();
|
||||
for (int i=0; i<size; i++) {
|
||||
Rect invalidRect = invalidList.get(i);
|
||||
try
|
||||
{
|
||||
rfb.writeFramebufferUpdateRequest(invalidRect.left, invalidRect.top, invalidRect.right-invalidRect.left, invalidRect.bottom-invalidRect.top, false);
|
||||
pendingList.add(invalidRect);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
//TODO Log this
|
||||
}
|
||||
}
|
||||
waitingForInput=true;
|
||||
//android.util.Log.i("LBM", "pending "+pendingList.toString() + "invalid "+invalidList.toString());
|
||||
}
|
||||
}
|
||||
33
app/src/main/java/android/androidVNC/MemInStream.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
public class MemInStream extends InStream {
|
||||
|
||||
public MemInStream(byte[] data, int offset, int len) {
|
||||
b = data;
|
||||
ptr = offset;
|
||||
end = offset + len;
|
||||
}
|
||||
|
||||
public int pos() { return ptr; }
|
||||
|
||||
protected int overrun(int itemSize, int nItems) throws Exception {
|
||||
throw new Exception("MemInStream overrun: end of stream");
|
||||
}
|
||||
}
|
||||
50
app/src/main/java/android/androidVNC/MetaKeyBase.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class MetaKeyBase implements Comparable<MetaKeyBase> {
|
||||
int keySym;
|
||||
int mouseButtons;
|
||||
int keyEvent;
|
||||
String name;
|
||||
boolean isMouse;
|
||||
boolean isKeyEvent;
|
||||
|
||||
MetaKeyBase(int mouseButtons, String name)
|
||||
{
|
||||
this.mouseButtons = mouseButtons;
|
||||
this.name = name;
|
||||
this.isMouse = true;
|
||||
this.isKeyEvent = false;
|
||||
}
|
||||
|
||||
MetaKeyBase(String name, int keySym, int keyEvent)
|
||||
{
|
||||
this.name = name;
|
||||
this.keySym = keySym;
|
||||
this.keyEvent = keyEvent;
|
||||
this.isMouse = false;
|
||||
this.isKeyEvent = true;
|
||||
}
|
||||
|
||||
MetaKeyBase(String name, int keySym)
|
||||
{
|
||||
this.name = name;
|
||||
this.keySym = keySym;
|
||||
this.isMouse = false;
|
||||
this.isKeyEvent = false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(MetaKeyBase another) {
|
||||
return name.compareTo(another.name);
|
||||
}
|
||||
}
|
||||
269
app/src/main/java/android/androidVNC/MetaKeyBean.java
Normal file
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.antlersoft.android.dbimpl.NewInstance;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class MetaKeyBean extends AbstractMetaKeyBean implements Comparable<MetaKeyBean> {
|
||||
static final ArrayList<MetaKeyBase> allKeys;
|
||||
static final String[] allKeysNames;
|
||||
static final HashMap<Integer,MetaKeyBase> keysByKeyCode;
|
||||
static final HashMap<Integer,MetaKeyBase> keysByMouseButton;
|
||||
static final HashMap<Integer,MetaKeyBase> keysByKeySym;
|
||||
static final MetaKeyBean keyCtrlAltDel;
|
||||
static final MetaKeyBean keyArrowLeft;
|
||||
static final MetaKeyBean keyArrowRight;
|
||||
static final MetaKeyBean keyArrowUp;
|
||||
static final MetaKeyBean keyArrowDown;
|
||||
|
||||
static final NewInstance<MetaKeyBean> NEW;
|
||||
|
||||
static {
|
||||
allKeys = new ArrayList<MetaKeyBase>();
|
||||
|
||||
allKeys.add(new MetaKeyBase("Hangul", 0xff31));
|
||||
allKeys.add(new MetaKeyBase("Hangul_Start", 0xff32));
|
||||
allKeys.add(new MetaKeyBase("Hangul_End", 0xff33));
|
||||
allKeys.add(new MetaKeyBase("Hangul_Hanja", 0xff34));
|
||||
allKeys.add(new MetaKeyBase("Kana_Shift", 0xff2e));
|
||||
allKeys.add(new MetaKeyBase("Right_Alt", 0xffea));
|
||||
|
||||
allKeys.add(new MetaKeyBase(VncCanvas.MOUSE_BUTTON_LEFT,"Mouse Left"));
|
||||
allKeys.add(new MetaKeyBase(VncCanvas.MOUSE_BUTTON_MIDDLE,"Mouse Middle"));
|
||||
allKeys.add(new MetaKeyBase(VncCanvas.MOUSE_BUTTON_RIGHT,"Mouse Right"));
|
||||
allKeys.add(new MetaKeyBase(VncCanvas.MOUSE_BUTTON_SCROLL_DOWN, "Mouse Scroll Down"));
|
||||
allKeys.add(new MetaKeyBase(VncCanvas.MOUSE_BUTTON_SCROLL_UP, "Mouse Scroll Up"));
|
||||
|
||||
allKeys.add(new MetaKeyBase("Home", 0xFF50));
|
||||
allKeys.add(new MetaKeyBase("Arrow Left", 0xFF51));
|
||||
allKeys.add(new MetaKeyBase("Arrow Up", 0xFF52));
|
||||
allKeys.add(new MetaKeyBase("Arrow Right", 0xFF53));
|
||||
allKeys.add(new MetaKeyBase("Arrow Down", 0xFF54));
|
||||
allKeys.add(new MetaKeyBase("Page Up", 0xFF55));
|
||||
allKeys.add(new MetaKeyBase("Page Down", 0xFF56));
|
||||
allKeys.add(new MetaKeyBase("End", 0xFF57));
|
||||
allKeys.add(new MetaKeyBase("Insert", 0xFF63));
|
||||
allKeys.add(new MetaKeyBase("Delete", 0xFFFF, KeyEvent.KEYCODE_DEL));
|
||||
allKeys.add(new MetaKeyBase("Num Lock", 0xFF7F));
|
||||
allKeys.add(new MetaKeyBase("Break", 0xFF6b));
|
||||
allKeys.add(new MetaKeyBase("Scroll Lock", 0xFF14));
|
||||
allKeys.add(new MetaKeyBase("Print Scrn", 0xFF15));
|
||||
allKeys.add(new MetaKeyBase("Escape", 0xFF1B));
|
||||
allKeys.add(new MetaKeyBase("Enter", 0xFF0D, KeyEvent.KEYCODE_ENTER));
|
||||
allKeys.add(new MetaKeyBase("Tab", 0xFF09, KeyEvent.KEYCODE_TAB));
|
||||
allKeys.add(new MetaKeyBase("BackSpace", 0xFF08));
|
||||
allKeys.add(new MetaKeyBase("Space", 0x020, KeyEvent.KEYCODE_SPACE));
|
||||
|
||||
StringBuilder sb = new StringBuilder(" ");
|
||||
for (int i=0; i<26; i++)
|
||||
{
|
||||
sb.setCharAt(0, (char)('A' + i));
|
||||
allKeys.add(new MetaKeyBase(sb.toString(), 'a' + i, KeyEvent.KEYCODE_A + i));
|
||||
}
|
||||
|
||||
for (int i=0; i<10; i++)
|
||||
{
|
||||
sb.setCharAt(0, (char)('0' + i));
|
||||
allKeys.add(new MetaKeyBase(sb.toString(), '0' + i, KeyEvent.KEYCODE_0 + i));
|
||||
}
|
||||
|
||||
for (int i=0; i<12; i++)
|
||||
{
|
||||
sb.setLength(0);
|
||||
sb.append('F');
|
||||
if (i<9)
|
||||
sb.append(' ');
|
||||
sb.append(Integer.toString(i+1));
|
||||
allKeys.add(new MetaKeyBase(sb.toString(), 0xFFBE + i));
|
||||
}
|
||||
|
||||
java.util.Collections.sort(allKeys);
|
||||
allKeysNames = new String[allKeys.size()];
|
||||
keysByKeyCode = new HashMap<Integer,MetaKeyBase>();
|
||||
keysByMouseButton = new HashMap<Integer,MetaKeyBase>();
|
||||
keysByKeySym = new HashMap<Integer,MetaKeyBase>();
|
||||
for (int i=0; i<allKeysNames.length; ++i)
|
||||
{
|
||||
MetaKeyBase b=allKeys.get(i);
|
||||
allKeysNames[i] = b.name;
|
||||
if (b.isKeyEvent)
|
||||
keysByKeyCode.put(b.keyEvent,b);
|
||||
if (b.isMouse)
|
||||
keysByMouseButton.put(b.mouseButtons,b);
|
||||
else
|
||||
keysByKeySym.put(b.keySym,b);
|
||||
}
|
||||
NEW = new NewInstance<MetaKeyBean>() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.dbimpl.NewInstance#get()
|
||||
*/
|
||||
@Override
|
||||
public MetaKeyBean get() {
|
||||
return new MetaKeyBean();
|
||||
}
|
||||
};
|
||||
keyCtrlAltDel = new MetaKeyBean(0,VncCanvas.CTRL_MASK|VncCanvas.ALT_MASK,keysByKeyCode.get(KeyEvent.KEYCODE_DEL));
|
||||
keyArrowLeft = new MetaKeyBean(0,0,keysByKeySym.get(0xFF51));
|
||||
keyArrowUp = new MetaKeyBean(0,0,keysByKeySym.get(0xFF52));
|
||||
keyArrowRight = new MetaKeyBean(0,0,keysByKeySym.get(0xFF53));
|
||||
keyArrowDown = new MetaKeyBean(0,0,keysByKeySym.get(0xFF54));
|
||||
}
|
||||
|
||||
private boolean _regenDesc;
|
||||
|
||||
MetaKeyBean()
|
||||
{
|
||||
}
|
||||
|
||||
MetaKeyBean(MetaKeyBean toCopy)
|
||||
{
|
||||
_regenDesc = true;
|
||||
if (toCopy.isMouseClick())
|
||||
setMouseButtons(toCopy.getMouseButtons());
|
||||
else
|
||||
setKeySym(toCopy.getKeySym());
|
||||
setMetaListId(toCopy.getMetaListId());
|
||||
setMetaFlags(toCopy.getMetaFlags());
|
||||
}
|
||||
|
||||
MetaKeyBean(long listId, int metaFlags, MetaKeyBase base)
|
||||
{
|
||||
setMetaListId(listId);
|
||||
setKeyBase(base);
|
||||
setMetaFlags(metaFlags);
|
||||
_regenDesc = true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractMetaKeyBean#getKeyDesc()
|
||||
*/
|
||||
@Override
|
||||
public String getKeyDesc() {
|
||||
if (_regenDesc)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
if (_regenDesc)
|
||||
{
|
||||
StringBuilder sb=new StringBuilder();
|
||||
int meta=getMetaFlags();
|
||||
if (0 != (meta & VncCanvas.SHIFT_MASK))
|
||||
{
|
||||
sb.append("Shift");
|
||||
}
|
||||
if (0 != (meta & VncCanvas.CTRL_MASK))
|
||||
{
|
||||
if (sb.length()>0)
|
||||
sb.append('-');
|
||||
sb.append("Ctrl");
|
||||
}
|
||||
if (0 != (meta & VncCanvas.ALT_MASK))
|
||||
{
|
||||
if (sb.length()>0)
|
||||
sb.append('-');
|
||||
sb.append("Alt");
|
||||
}
|
||||
if (sb.length()>0)
|
||||
sb.append(' ');
|
||||
MetaKeyBase base;
|
||||
if (isMouseClick())
|
||||
base=keysByMouseButton.get(getMouseButtons());
|
||||
else
|
||||
base=keysByKeySym.get(getKeySym());
|
||||
sb.append(base.name);
|
||||
setKeyDesc(sb.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.getKeyDesc();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractMetaKeyBean#setKeyDesc(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setKeyDesc(String arg_keyDesc) {
|
||||
super.setKeyDesc(arg_keyDesc);
|
||||
_regenDesc = false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractMetaKeyBean#setKeySym(int)
|
||||
*/
|
||||
@Override
|
||||
public void setKeySym(int arg_keySym) {
|
||||
if (arg_keySym!=getKeySym() || isMouseClick())
|
||||
{
|
||||
setMouseClick(false);
|
||||
_regenDesc=true;
|
||||
super.setKeySym(arg_keySym);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractMetaKeyBean#setMetaFlags(int)
|
||||
*/
|
||||
@Override
|
||||
public void setMetaFlags(int arg_metaFlags) {
|
||||
if (arg_metaFlags != getMetaFlags())
|
||||
{
|
||||
_regenDesc = true;
|
||||
super.setMetaFlags(arg_metaFlags);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractMetaKeyBean#setMouseButtons(int)
|
||||
*/
|
||||
@Override
|
||||
public void setMouseButtons(int arg_mouseButtons) {
|
||||
if (arg_mouseButtons!=getMouseButtons() || ! isMouseClick())
|
||||
{
|
||||
setMouseClick(true);
|
||||
_regenDesc = true;
|
||||
super.setMouseButtons(arg_mouseButtons);
|
||||
}
|
||||
}
|
||||
|
||||
void setKeyBase(MetaKeyBase base)
|
||||
{
|
||||
if (base.isMouse)
|
||||
{
|
||||
setMouseButtons(base.mouseButtons);
|
||||
}
|
||||
else
|
||||
{
|
||||
setKeySym(base.keySym);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof MetaKeyBean)
|
||||
{
|
||||
return getKeyDesc().equals(((MetaKeyBean)o).getKeyDesc());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(MetaKeyBean another) {
|
||||
return getKeyDesc().compareTo(another.getKeyDesc());
|
||||
}
|
||||
}
|
||||
602
app/src/main/java/android/androidVNC/MetaKeyDialog.java
Normal file
@@ -0,0 +1,602 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.*;
|
||||
import android.database.*;
|
||||
import android.database.sqlite.*;
|
||||
import android.os.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import android.widget.AdapterView.*;
|
||||
import android.widget.CompoundButton.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.util.Map.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class MetaKeyDialog extends Dialog implements ConnectionSettable {
|
||||
|
||||
CheckBox _checkShift;
|
||||
CheckBox _checkCtrl;
|
||||
CheckBox _checkAlt;
|
||||
TextView _textKeyDesc;
|
||||
EditText _textListName;
|
||||
Spinner _spinnerKeySelect;
|
||||
Spinner _spinnerKeysInList;
|
||||
Spinner _spinnerLists;
|
||||
|
||||
VncDatabase _database;
|
||||
static ArrayList<MetaList> _lists;
|
||||
ArrayList<MetaKeyBean> _keysInList;
|
||||
long _listId;
|
||||
VncCanvasActivity _canvasActivity;
|
||||
MetaKeyBean _currentKeyBean;
|
||||
|
||||
static final String[] EMPTY_ARGS = new String[0];
|
||||
|
||||
ConnectionBean _connection;
|
||||
|
||||
/**
|
||||
* @param context
|
||||
*/
|
||||
public MetaKeyDialog(Context context) {
|
||||
super(context);
|
||||
setOwnerActivity((Activity)context);
|
||||
_canvasActivity = (VncCanvasActivity)context;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onCreateOptionsMenu(android.view.Menu)
|
||||
*/
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
_canvasActivity.getMenuInflater().inflate(R.menu.metakeymenu, menu);
|
||||
menu.findItem(R.id.itemDeleteKeyList).setOnMenuItemClickListener(
|
||||
new MenuItem.OnMenuItemClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.view.MenuItem.OnMenuItemClickListener#onMenuItemClick(android.view.MenuItem)
|
||||
*/
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
Utils.showYesNoPrompt(_canvasActivity, "Delete key list",
|
||||
"Delete list "+_textListName.getText().toString(),
|
||||
new OnClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.content.DialogInterface.OnClickListener#onClick(android.content.DialogInterface, int)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
int position = _spinnerLists.getSelectedItemPosition();
|
||||
if (position == Spinner.INVALID_POSITION)
|
||||
return;
|
||||
_listId = _lists.get(position).get_Id();
|
||||
if (_listId > 1)
|
||||
{
|
||||
_lists.remove(position);
|
||||
ArrayAdapter<String> adapter = getSpinnerAdapter(_spinnerLists);
|
||||
adapter.remove(adapter.getItem(position));
|
||||
SQLiteDatabase db = _database.getWritableDatabase();
|
||||
db.execSQL(MessageFormat.format("DELETE FROM {0} WHERE {1} = {2}",
|
||||
MetaKeyBean.GEN_TABLE_NAME, MetaKeyBean.GEN_FIELD_METALISTID,
|
||||
_listId));
|
||||
db.execSQL(MessageFormat.format("DELETE FROM {0} WHERE {1} = {2}",
|
||||
MetaList.GEN_TABLE_NAME, MetaList.GEN_FIELD__ID,
|
||||
_listId));
|
||||
_connection.setMetaListId(1);
|
||||
_connection.save(db);
|
||||
setMetaKeyList();
|
||||
}
|
||||
}
|
||||
},
|
||||
null);
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
menu.findItem(R.id.itemDeleteKey).setOnMenuItemClickListener(
|
||||
new MenuItem.OnMenuItemClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.view.MenuItem.OnMenuItemClickListener#onMenuItemClick(android.view.MenuItem)
|
||||
*/
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
final int position = _spinnerKeysInList.getSelectedItemPosition();
|
||||
if (position != Spinner.INVALID_POSITION)
|
||||
{
|
||||
final MetaKeyBean toDelete = _keysInList.get(position);
|
||||
Utils.showYesNoPrompt(_canvasActivity, "Delete from list",
|
||||
"Delete key " + toDelete.getKeyDesc(),
|
||||
new OnClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.content.DialogInterface.OnClickListener#onClick(android.content.DialogInterface, int)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
getSpinnerAdapter(_spinnerKeysInList).remove(toDelete.getKeyDesc());
|
||||
_keysInList.remove(position);
|
||||
SQLiteDatabase db = _database.getWritableDatabase();
|
||||
db.execSQL(
|
||||
MessageFormat.format("DELETE FROM {0} WHERE {1} = {2}",
|
||||
MetaKeyBean.GEN_TABLE_NAME, MetaKeyBean.GEN_FIELD_METALISTID,
|
||||
toDelete.get_Id())
|
||||
);
|
||||
if (_connection.getLastMetaKeyId() == toDelete.get_Id())
|
||||
{
|
||||
_connection.setLastMetaKeyId(0);
|
||||
_connection.save(db);
|
||||
}
|
||||
int newPos = _spinnerKeysInList.getSelectedItemPosition();
|
||||
if (newPos != Spinner.INVALID_POSITION && newPos < _keysInList.size())
|
||||
{
|
||||
_currentKeyBean = new MetaKeyBean(_keysInList.get(newPos));
|
||||
updateDialogForCurrentKey();
|
||||
}
|
||||
}
|
||||
},
|
||||
null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onMenuOpened(int, android.view.Menu)
|
||||
*/
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.findItem(R.id.itemDeleteKeyList).setEnabled(_currentKeyBean.getMetaListId()>1);
|
||||
menu.findItem(R.id.itemDeleteKey).setEnabled(_spinnerKeysInList.getSelectedItemPosition()!=Spinner.INVALID_POSITION);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onCreate(android.os.Bundle)
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.metakey);
|
||||
setTitle(R.string.meta_key_title);
|
||||
_checkShift = (CheckBox)findViewById(R.id.checkboxShift);
|
||||
_checkCtrl = (CheckBox)findViewById(R.id.checkboxCtrl);
|
||||
_checkAlt = (CheckBox)findViewById(R.id.checkboxAlt);
|
||||
_textKeyDesc = (TextView)findViewById(R.id.textKeyDesc);
|
||||
_textListName = (EditText)findViewById(R.id.textListName);
|
||||
_spinnerKeySelect = (Spinner)findViewById(R.id.spinnerKeySelect);
|
||||
_spinnerKeysInList = (Spinner)findViewById(R.id.spinnerKeysInList);
|
||||
_spinnerLists = (Spinner)findViewById(R.id.spinnerLists);
|
||||
|
||||
_database = _canvasActivity.database;
|
||||
if (_lists == null) {
|
||||
_lists = new ArrayList<MetaList>();
|
||||
MetaList.getAll(_database.getReadableDatabase(), MetaList.GEN_TABLE_NAME, _lists, MetaList.GEN_NEW);
|
||||
}
|
||||
_spinnerKeySelect.setAdapter(new ArrayAdapter<String>(getOwnerActivity(), android.R.layout.simple_spinner_item, MetaKeyBean.allKeysNames));
|
||||
_spinnerKeySelect.setSelection(0);
|
||||
|
||||
setListSpinner();
|
||||
|
||||
_checkShift.setOnCheckedChangeListener(new MetaCheckListener(VncCanvas.SHIFT_MASK));
|
||||
_checkAlt.setOnCheckedChangeListener(new MetaCheckListener(VncCanvas.ALT_MASK));
|
||||
_checkCtrl.setOnCheckedChangeListener(new MetaCheckListener(VncCanvas.CTRL_MASK));
|
||||
|
||||
_spinnerLists.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View, int, long)
|
||||
*/
|
||||
public void onItemSelected(AdapterView<?> parent, View view,
|
||||
int position, long id) {
|
||||
_connection.setMetaListId(_lists.get(position).get_Id());
|
||||
_connection.Gen_update(_database.getWritableDatabase());
|
||||
setMetaKeyList();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.widget.AdapterView.OnItemSelectedListener#onNothingSelected(android.widget.AdapterView)
|
||||
*/
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
_spinnerKeysInList.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View, int, long)
|
||||
*/
|
||||
public void onItemSelected(AdapterView<?> parent, View view,
|
||||
int position, long id) {
|
||||
_currentKeyBean = new MetaKeyBean(_keysInList.get(position));
|
||||
updateDialogForCurrentKey();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.widget.AdapterView.OnItemSelectedListener#onNothingSelected(android.widget.AdapterView)
|
||||
*/
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
|
||||
_spinnerKeySelect.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View, int, long)
|
||||
*/
|
||||
public void onItemSelected(AdapterView<?> parent, View view,
|
||||
int position, long id) {
|
||||
if (_currentKeyBean == null) {
|
||||
_currentKeyBean = new MetaKeyBean(0,0,MetaKeyBean.allKeys.get(position));
|
||||
}
|
||||
else {
|
||||
_currentKeyBean.setKeyBase(MetaKeyBean.allKeys.get(position));
|
||||
}
|
||||
updateDialogForCurrentKey();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.widget.AdapterView.OnItemSelectedListener#onNothingSelected(android.widget.AdapterView)
|
||||
*/
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
|
||||
((Button)findViewById(R.id.buttonSend)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.view.View.OnClickListener#onClick(android.view.View)
|
||||
*/
|
||||
public void onClick(View v) {
|
||||
sendCurrentKey();
|
||||
dismiss();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
((Button)findViewById(R.id.buttonNewList)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.view.View.OnClickListener#onClick(android.view.View)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MetaList newList = new MetaList();
|
||||
newList.setName("New");
|
||||
SQLiteDatabase db = _database.getWritableDatabase();
|
||||
newList.Gen_insert(db);
|
||||
_connection.setMetaListId(newList.get_Id());
|
||||
_connection.save(db);
|
||||
_lists.add(newList);
|
||||
getSpinnerAdapter(_spinnerLists).add(newList.getName());
|
||||
setMetaKeyList();
|
||||
}
|
||||
|
||||
});
|
||||
((Button)findViewById(R.id.buttonCopyList)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.view.View.OnClickListener#onClick(android.view.View)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MetaList newList = new MetaList();
|
||||
newList.setName("Copy of " + _textListName.getText().toString());
|
||||
SQLiteDatabase db = _database.getWritableDatabase();
|
||||
newList.Gen_insert(db);
|
||||
db.execSQL(MessageFormat.format(getCopyListString(), newList.get_Id(), _listId));
|
||||
_connection.setMetaListId(newList.get_Id());
|
||||
_connection.save(db);
|
||||
_lists.add(newList);
|
||||
getSpinnerAdapter(_spinnerLists).add(newList.getName());
|
||||
setMetaKeyList();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private static String copyListString;
|
||||
|
||||
private String getCopyListString()
|
||||
{
|
||||
if (copyListString==null)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder("INSERT INTO ");
|
||||
sb.append(MetaKeyBean.GEN_TABLE_NAME);
|
||||
sb.append(" ( ");
|
||||
sb.append(MetaKeyBean.GEN_FIELD_METALISTID);
|
||||
StringBuilder fieldList = new StringBuilder();
|
||||
for (Entry<String,Object> s : _currentKeyBean.Gen_getValues().valueSet())
|
||||
{
|
||||
if (!s.getKey().equals(MetaKeyBean.GEN_FIELD__ID) && !s.getKey().equals(MetaKeyBean.GEN_FIELD_METALISTID)) {
|
||||
fieldList.append(',');
|
||||
fieldList.append(s.getKey());
|
||||
}
|
||||
}
|
||||
String fl = fieldList.toString();
|
||||
sb.append(fl);
|
||||
sb.append(" ) SELECT {0} ");
|
||||
sb.append(fl);
|
||||
sb.append(" FROM ");
|
||||
sb.append(MetaKeyBean.GEN_TABLE_NAME);
|
||||
sb.append(" WHERE ");
|
||||
sb.append(MetaKeyBean.GEN_FIELD_METALISTID);
|
||||
sb.append(" = {1}");
|
||||
copyListString = sb.toString();
|
||||
}
|
||||
return copyListString;
|
||||
}
|
||||
|
||||
private boolean _justStarted;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onStart()
|
||||
*/
|
||||
@Override
|
||||
protected void onStart() {
|
||||
takeKeyEvents(true);
|
||||
_justStarted = true;
|
||||
super.onStart();
|
||||
View v = getCurrentFocus();
|
||||
if (v!=null)
|
||||
v.clearFocus();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onStop()
|
||||
*/
|
||||
@Override
|
||||
protected void onStop() {
|
||||
int i = 0;
|
||||
for (MetaList l : _lists)
|
||||
{
|
||||
if (l.get_Id() == _listId)
|
||||
{
|
||||
String s = _textListName.getText().toString();
|
||||
if (! s.equals(l.getName()))
|
||||
{
|
||||
l.setName(s);
|
||||
l.Gen_update(_database.getWritableDatabase());
|
||||
ArrayAdapter<String> adapter = getSpinnerAdapter(_spinnerLists);
|
||||
adapter.remove(adapter.getItem(i));
|
||||
adapter.insert(s,i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
takeKeyEvents(false);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onKeyDown(int, android.view.KeyEvent)
|
||||
*/
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
_justStarted = false;
|
||||
if (keyCode != KeyEvent.KEYCODE_BACK && keyCode != KeyEvent.KEYCODE_MENU && getCurrentFocus() == null)
|
||||
{
|
||||
int flags = event.getMetaState();
|
||||
int currentFlags = _currentKeyBean.getMetaFlags();
|
||||
MetaKeyBase base = MetaKeyBean.keysByKeyCode.get(keyCode);
|
||||
if (base != null)
|
||||
{
|
||||
if (0 != (flags & KeyEvent.META_SHIFT_ON))
|
||||
{
|
||||
currentFlags |= VncCanvas.SHIFT_MASK;
|
||||
}
|
||||
if (0 != (flags & KeyEvent.META_ALT_ON))
|
||||
{
|
||||
currentFlags |= VncCanvas.ALT_MASK;
|
||||
}
|
||||
_currentKeyBean.setKeyBase(base);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Toggle flags according to meta keys
|
||||
if (0 != (flags & KeyEvent.META_SHIFT_ON))
|
||||
{
|
||||
currentFlags ^= VncCanvas.SHIFT_MASK;
|
||||
}
|
||||
if (0 != (flags & KeyEvent.META_ALT_ON))
|
||||
{
|
||||
currentFlags ^= VncCanvas.ALT_MASK;
|
||||
}
|
||||
if (keyCode == KeyEvent.KEYCODE_SEARCH)
|
||||
{
|
||||
currentFlags ^= VncCanvas.CTRL_MASK;
|
||||
}
|
||||
}
|
||||
_currentKeyBean.setMetaFlags(currentFlags);
|
||||
updateDialogForCurrentKey();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onKeyUp(int, android.view.KeyEvent)
|
||||
*/
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (! _justStarted && keyCode != KeyEvent.KEYCODE_BACK && keyCode != KeyEvent.KEYCODE_MENU && getCurrentFocus()==null)
|
||||
{
|
||||
if (MetaKeyBean.keysByKeyCode.get(keyCode) != null)
|
||||
{
|
||||
sendCurrentKey();
|
||||
dismiss();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
_justStarted = false;
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static ArrayAdapter<String> getSpinnerAdapter(Spinner spinner)
|
||||
{
|
||||
return (ArrayAdapter<String>)spinner.getAdapter();
|
||||
}
|
||||
|
||||
void sendCurrentKey()
|
||||
{
|
||||
int index = Collections.binarySearch(_keysInList, _currentKeyBean);
|
||||
SQLiteDatabase db = _database.getWritableDatabase();
|
||||
if (index < 0)
|
||||
{
|
||||
int insertionPoint = -(index + 1);
|
||||
_currentKeyBean.Gen_insert(db);
|
||||
_keysInList.add(insertionPoint,_currentKeyBean);
|
||||
getSpinnerAdapter(_spinnerKeysInList).insert(_currentKeyBean.getKeyDesc(), insertionPoint);
|
||||
_spinnerKeysInList.setSelection(insertionPoint);
|
||||
_connection.setLastMetaKeyId(_currentKeyBean.get_Id());
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaKeyBean bean = _keysInList.get(index);
|
||||
_connection.setLastMetaKeyId(bean.get_Id());
|
||||
_spinnerKeysInList.setSelection(index);
|
||||
}
|
||||
_connection.Gen_update(db);
|
||||
_canvasActivity.vncCanvas.sendMetaKey(_currentKeyBean);
|
||||
}
|
||||
|
||||
void setMetaKeyList()
|
||||
{
|
||||
long listId = _connection.getMetaListId();
|
||||
if (listId!=_listId) {
|
||||
for (int i=0; i<_lists.size(); ++i)
|
||||
{
|
||||
MetaList list = _lists.get(i);
|
||||
if (list.get_Id()==listId)
|
||||
{
|
||||
_spinnerLists.setSelection(i);
|
||||
_keysInList = new ArrayList<MetaKeyBean>();
|
||||
Cursor c = _database.getReadableDatabase().rawQuery(
|
||||
MessageFormat.format("SELECT * FROM {0} WHERE {1} = {2} ORDER BY KEYDESC",
|
||||
MetaKeyBean.GEN_TABLE_NAME,
|
||||
MetaKeyBean.GEN_FIELD_METALISTID,
|
||||
listId),
|
||||
EMPTY_ARGS);
|
||||
MetaKeyBean.Gen_populateFromCursor(
|
||||
c,
|
||||
_keysInList,
|
||||
MetaKeyBean.NEW);
|
||||
c.close();
|
||||
ArrayList<String> keys = new ArrayList<String>(_keysInList.size());
|
||||
int selectedOffset = 0;
|
||||
long lastSelectedKeyId = _canvasActivity.getConnection().getLastMetaKeyId();
|
||||
for (int j=0; j<_keysInList.size(); j++)
|
||||
{
|
||||
MetaKeyBean key = _keysInList.get(j);
|
||||
keys.add( key.getKeyDesc());
|
||||
if (lastSelectedKeyId==key.get_Id())
|
||||
{
|
||||
selectedOffset = j;
|
||||
}
|
||||
}
|
||||
_spinnerKeysInList.setAdapter(new ArrayAdapter<String>(getOwnerActivity(), android.R.layout.simple_spinner_item, keys));
|
||||
if (keys.size()>0)
|
||||
{
|
||||
_spinnerKeysInList.setSelection(selectedOffset);
|
||||
_currentKeyBean = new MetaKeyBean(_keysInList.get(selectedOffset));
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentKeyBean = new MetaKeyBean(listId, 0, MetaKeyBean.allKeys.get(0));
|
||||
}
|
||||
updateDialogForCurrentKey();
|
||||
_textListName.setText(list.getName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
_listId = listId;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDialogForCurrentKey()
|
||||
{
|
||||
int flags = _currentKeyBean.getMetaFlags();
|
||||
_checkAlt.setChecked(0 != (flags & VncCanvas.ALT_MASK));
|
||||
_checkShift.setChecked(0 != (flags & VncCanvas.SHIFT_MASK));
|
||||
_checkCtrl.setChecked(0 != (flags & VncCanvas.CTRL_MASK));
|
||||
MetaKeyBase base = null;
|
||||
if (_currentKeyBean.isMouseClick())
|
||||
{
|
||||
base = MetaKeyBean.keysByMouseButton.get(_currentKeyBean.getMouseButtons());
|
||||
} else {
|
||||
base = MetaKeyBean.keysByKeySym.get(_currentKeyBean.getKeySym());
|
||||
}
|
||||
if (base != null) {
|
||||
int index = Collections.binarySearch(MetaKeyBean.allKeys,base);
|
||||
if (index >= 0) {
|
||||
_spinnerKeySelect.setSelection(index);
|
||||
}
|
||||
}
|
||||
_textKeyDesc.setText(_currentKeyBean.getKeyDesc());
|
||||
}
|
||||
|
||||
public void setConnection(ConnectionBean conn)
|
||||
{
|
||||
if ( _connection != conn) {
|
||||
_connection = conn;
|
||||
setMetaKeyList();
|
||||
}
|
||||
}
|
||||
|
||||
void setListSpinner()
|
||||
{
|
||||
ArrayList<String> listNames = new ArrayList<String>(_lists.size());
|
||||
for (int i=0; i<_lists.size(); ++i)
|
||||
{
|
||||
MetaList l = _lists.get(i);
|
||||
listNames.add(l.getName());
|
||||
}
|
||||
_spinnerLists.setAdapter(new ArrayAdapter<String>(getOwnerActivity(),android.R.layout.simple_spinner_item, listNames));
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class MetaCheckListener implements OnCheckedChangeListener {
|
||||
|
||||
private int _mask;
|
||||
|
||||
MetaCheckListener(int mask) {
|
||||
_mask = mask;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see android.widget.CompoundButton.OnCheckedChangeListener#onCheckedChanged(android.widget.CompoundButton, boolean)
|
||||
*/
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView,
|
||||
boolean isChecked) {
|
||||
if (isChecked)
|
||||
{
|
||||
_currentKeyBean.setMetaFlags(_currentKeyBean.getMetaFlags() | _mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentKeyBean.setMetaFlags(_currentKeyBean.getMetaFlags() & ~_mask);
|
||||
}
|
||||
_textKeyDesc.setText(_currentKeyBean.getKeyDesc());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
84
app/src/main/java/android/androidVNC/MetaList.java
Normal file
@@ -0,0 +1,84 @@
|
||||
// This class was generated from android.androidVNC.IMetaList by a tool
|
||||
// Do not edit this file directly! PLX THX
|
||||
package android.androidVNC;
|
||||
|
||||
public class MetaList extends com.antlersoft.android.dbimpl.IdImplementationBase implements IMetaList {
|
||||
|
||||
public static final String GEN_TABLE_NAME = "META_LIST";
|
||||
public static final int GEN_COUNT = 2;
|
||||
|
||||
// Field constants
|
||||
public static final String GEN_FIELD__ID = "_id";
|
||||
public static final int GEN_ID__ID = 0;
|
||||
public static final String GEN_FIELD_NAME = "NAME";
|
||||
public static final int GEN_ID_NAME = 1;
|
||||
|
||||
// SQL Command for creating the table
|
||||
public static String GEN_CREATE = "CREATE TABLE META_LIST (" +
|
||||
"_id INTEGER PRIMARY KEY AUTOINCREMENT," +
|
||||
"NAME TEXT" +
|
||||
")";
|
||||
|
||||
// Members corresponding to defined fields
|
||||
private long gen__Id;
|
||||
private java.lang.String gen_name;
|
||||
|
||||
|
||||
public static final com.antlersoft.android.dbimpl.NewInstance<MetaList> GEN_NEW = new com.antlersoft.android.dbimpl.NewInstance<MetaList>() {
|
||||
public MetaList get() {
|
||||
return new MetaList();
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
public String Gen_tableName() { return GEN_TABLE_NAME; }
|
||||
|
||||
// Field accessors
|
||||
public long get_Id() { return gen__Id; }
|
||||
public void set_Id(long arg__Id) { gen__Id = arg__Id; }
|
||||
public java.lang.String getName() { return gen_name; }
|
||||
public void setName(java.lang.String arg_name) { gen_name = arg_name; }
|
||||
|
||||
public android.content.ContentValues Gen_getValues() {
|
||||
android.content.ContentValues values=new android.content.ContentValues();
|
||||
values.put(GEN_FIELD__ID,Long.toString(this.gen__Id));
|
||||
values.put(GEN_FIELD_NAME,this.gen_name);
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array that gives the column index in the cursor for each field defined
|
||||
* @param cursor Database cursor over some columns, possibly including this table
|
||||
* @return array of column indices; -1 if the column with that id is not in cursor
|
||||
*/
|
||||
public int[] Gen_columnIndices(android.database.Cursor cursor) {
|
||||
int[] result=new int[GEN_COUNT];
|
||||
result[0] = cursor.getColumnIndex(GEN_FIELD__ID);
|
||||
// Make compatible with database generated by older version of plugin with uppercase column name
|
||||
if (result[0] == -1) {
|
||||
result[0] = cursor.getColumnIndex("_ID");
|
||||
}
|
||||
result[1] = cursor.getColumnIndex(GEN_FIELD_NAME);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate one instance from a cursor
|
||||
*/
|
||||
public void Gen_populate(android.database.Cursor cursor,int[] columnIndices) {
|
||||
if ( columnIndices[GEN_ID__ID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID__ID])) {
|
||||
gen__Id = cursor.getLong(columnIndices[GEN_ID__ID]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_NAME] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_NAME])) {
|
||||
gen_name = cursor.getString(columnIndices[GEN_ID_NAME]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate one instance from a ContentValues
|
||||
*/
|
||||
public void Gen_populate(android.content.ContentValues values) {
|
||||
gen__Id = values.getAsLong(GEN_FIELD__ID);
|
||||
gen_name = values.getAsString(GEN_FIELD_NAME);
|
||||
}
|
||||
}
|
||||
108
app/src/main/java/android/androidVNC/MostRecentBean.java
Normal file
@@ -0,0 +1,108 @@
|
||||
// This class was generated from android.androidVNC.IMostRecentBean by a tool
|
||||
// Do not edit this file directly! PLX THX
|
||||
package android.androidVNC;
|
||||
|
||||
public class MostRecentBean extends com.antlersoft.android.dbimpl.IdImplementationBase implements IMostRecentBean {
|
||||
|
||||
public static final String GEN_TABLE_NAME = "MOST_RECENT";
|
||||
public static final int GEN_COUNT = 4;
|
||||
|
||||
// Field constants
|
||||
public static final String GEN_FIELD__ID = "_id";
|
||||
public static final int GEN_ID__ID = 0;
|
||||
public static final String GEN_FIELD_CONNECTION_ID = "CONNECTION_ID";
|
||||
public static final int GEN_ID_CONNECTION_ID = 1;
|
||||
public static final String GEN_FIELD_SHOW_SPLASH_VERSION = "SHOW_SPLASH_VERSION";
|
||||
public static final int GEN_ID_SHOW_SPLASH_VERSION = 2;
|
||||
public static final String GEN_FIELD_TEXT_INDEX = "TEXT_INDEX";
|
||||
public static final int GEN_ID_TEXT_INDEX = 3;
|
||||
|
||||
// SQL Command for creating the table
|
||||
public static String GEN_CREATE = "CREATE TABLE MOST_RECENT (" +
|
||||
"_id INTEGER PRIMARY KEY AUTOINCREMENT," +
|
||||
"CONNECTION_ID INTEGER," +
|
||||
"SHOW_SPLASH_VERSION INTEGER," +
|
||||
"TEXT_INDEX INTEGER" +
|
||||
")";
|
||||
|
||||
// Members corresponding to defined fields
|
||||
private long gen__Id;
|
||||
private long gen_CONNECTION_ID;
|
||||
private long gen_SHOW_SPLASH_VERSION;
|
||||
private long gen_TEXT_INDEX;
|
||||
|
||||
|
||||
public static final com.antlersoft.android.dbimpl.NewInstance<MostRecentBean> GEN_NEW = new com.antlersoft.android.dbimpl.NewInstance<MostRecentBean>() {
|
||||
public MostRecentBean get() {
|
||||
return new MostRecentBean();
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
public String Gen_tableName() { return GEN_TABLE_NAME; }
|
||||
|
||||
// Field accessors
|
||||
public long get_Id() { return gen__Id; }
|
||||
public void set_Id(long arg__Id) { gen__Id = arg__Id; }
|
||||
public long getConnectionId() { return gen_CONNECTION_ID; }
|
||||
public void setConnectionId(long arg_CONNECTION_ID) { gen_CONNECTION_ID = arg_CONNECTION_ID; }
|
||||
public long getShowSplashVersion() { return gen_SHOW_SPLASH_VERSION; }
|
||||
public void setShowSplashVersion(long arg_SHOW_SPLASH_VERSION) { gen_SHOW_SPLASH_VERSION = arg_SHOW_SPLASH_VERSION; }
|
||||
public long getTextIndex() { return gen_TEXT_INDEX; }
|
||||
public void setTextIndex(long arg_TEXT_INDEX) { gen_TEXT_INDEX = arg_TEXT_INDEX; }
|
||||
|
||||
public android.content.ContentValues Gen_getValues() {
|
||||
android.content.ContentValues values=new android.content.ContentValues();
|
||||
values.put(GEN_FIELD__ID,Long.toString(this.gen__Id));
|
||||
values.put(GEN_FIELD_CONNECTION_ID,Long.toString(this.gen_CONNECTION_ID));
|
||||
values.put(GEN_FIELD_SHOW_SPLASH_VERSION,Long.toString(this.gen_SHOW_SPLASH_VERSION));
|
||||
values.put(GEN_FIELD_TEXT_INDEX,Long.toString(this.gen_TEXT_INDEX));
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array that gives the column index in the cursor for each field defined
|
||||
* @param cursor Database cursor over some columns, possibly including this table
|
||||
* @return array of column indices; -1 if the column with that id is not in cursor
|
||||
*/
|
||||
public int[] Gen_columnIndices(android.database.Cursor cursor) {
|
||||
int[] result=new int[GEN_COUNT];
|
||||
result[0] = cursor.getColumnIndex(GEN_FIELD__ID);
|
||||
// Make compatible with database generated by older version of plugin with uppercase column name
|
||||
if (result[0] == -1) {
|
||||
result[0] = cursor.getColumnIndex("_ID");
|
||||
}
|
||||
result[1] = cursor.getColumnIndex(GEN_FIELD_CONNECTION_ID);
|
||||
result[2] = cursor.getColumnIndex(GEN_FIELD_SHOW_SPLASH_VERSION);
|
||||
result[3] = cursor.getColumnIndex(GEN_FIELD_TEXT_INDEX);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate one instance from a cursor
|
||||
*/
|
||||
public void Gen_populate(android.database.Cursor cursor,int[] columnIndices) {
|
||||
if ( columnIndices[GEN_ID__ID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID__ID])) {
|
||||
gen__Id = cursor.getLong(columnIndices[GEN_ID__ID]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_CONNECTION_ID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_CONNECTION_ID])) {
|
||||
gen_CONNECTION_ID = cursor.getLong(columnIndices[GEN_ID_CONNECTION_ID]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_SHOW_SPLASH_VERSION] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_SHOW_SPLASH_VERSION])) {
|
||||
gen_SHOW_SPLASH_VERSION = cursor.getLong(columnIndices[GEN_ID_SHOW_SPLASH_VERSION]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_TEXT_INDEX] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_TEXT_INDEX])) {
|
||||
gen_TEXT_INDEX = cursor.getLong(columnIndices[GEN_ID_TEXT_INDEX]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate one instance from a ContentValues
|
||||
*/
|
||||
public void Gen_populate(android.content.ContentValues values) {
|
||||
gen__Id = values.getAsLong(GEN_FIELD__ID);
|
||||
gen_CONNECTION_ID = values.getAsLong(GEN_FIELD_CONNECTION_ID);
|
||||
gen_SHOW_SPLASH_VERSION = values.getAsLong(GEN_FIELD_SHOW_SPLASH_VERSION);
|
||||
gen_TEXT_INDEX = values.getAsLong(GEN_FIELD_TEXT_INDEX);
|
||||
}
|
||||
}
|
||||
51
app/src/main/java/android/androidVNC/MouseMover.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright 2010 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* Specialization of panner that moves the mouse instead of panning the screen
|
||||
*
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class MouseMover extends Panner {
|
||||
|
||||
public MouseMover(VncCanvasActivity act, Handler hand) {
|
||||
super(act, hand);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
long interval = SystemClock.uptimeMillis() - lastSent;
|
||||
lastSent += interval;
|
||||
double scale = (double)interval / 50.0;
|
||||
VncCanvas canvas = activity.vncCanvas;
|
||||
//Log.v(TAG, String.format("panning %f %d %d", scale, (int)((double)velocity.x * scale), (int)((double)velocity.y * scale)));
|
||||
if ( canvas.processPointerEvent((int)(canvas.mouseX + ((double)velocity.x * scale)), (int)(canvas.mouseY + ((double)velocity.y * scale)), MotionEvent.ACTION_MOVE, 0, false, false))
|
||||
{
|
||||
if (updater.updateVelocity(velocity, interval))
|
||||
{
|
||||
handler.postDelayed(this, 50);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Log.v(TAG, "Updater requests stop");
|
||||
stop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Log.v(TAG, "Panning failed");
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
56
app/src/main/java/android/androidVNC/OneToOneScaling.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.widget.ImageView.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
class OneToOneScaling extends AbstractScaling {
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param scaleType
|
||||
*/
|
||||
public OneToOneScaling() {
|
||||
super(R.id.itemOneToOne,ScaleType.CENTER);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#getDefaultHandlerId()
|
||||
*/
|
||||
@Override
|
||||
int getDefaultHandlerId() {
|
||||
return R.id.itemInputTouchPanTrackballMouse;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#isAbleToPan()
|
||||
*/
|
||||
@Override
|
||||
boolean isAbleToPan() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#isValidInputMode(int)
|
||||
*/
|
||||
@Override
|
||||
boolean isValidInputMode(int mode) {
|
||||
return mode != R.id.itemInputFitToScreen;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#setScaleTypeForActivity(android.androidVNC.VncCanvasActivity)
|
||||
*/
|
||||
@Override
|
||||
void setScaleTypeForActivity(VncCanvasActivity activity) {
|
||||
super.setScaleTypeForActivity(activity);
|
||||
activity.vncCanvas.scrollToAbsolute();
|
||||
activity.vncCanvas.pan(0,0);
|
||||
}
|
||||
|
||||
}
|
||||
104
app/src/main/java/android/androidVNC/Panner.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
|
||||
/**
|
||||
* Handles panning the screen continuously over a period of time
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
class Panner implements Runnable {
|
||||
|
||||
VncCanvasActivity activity;
|
||||
Handler handler;
|
||||
PointF velocity;
|
||||
long lastSent;
|
||||
VelocityUpdater updater;
|
||||
|
||||
private static final String TAG = "PANNER";
|
||||
|
||||
/**
|
||||
* Specify how the panning velocity changes over time
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
interface VelocityUpdater {
|
||||
/**
|
||||
* Called approximately every 50 ms to update the velocity of panning
|
||||
* @param p X and Y components to update
|
||||
* @param interval Milliseconds since last update
|
||||
* @return False if the panning should stop immediately; true otherwise
|
||||
*/
|
||||
boolean updateVelocity(PointF p, long interval);
|
||||
}
|
||||
|
||||
static class DefaultUpdater implements VelocityUpdater {
|
||||
|
||||
static DefaultUpdater instance = new DefaultUpdater();
|
||||
|
||||
/**
|
||||
* Don't change velocity
|
||||
*/
|
||||
@Override
|
||||
public boolean updateVelocity(PointF p, long interval) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Panner(VncCanvasActivity act, Handler hand) {
|
||||
activity = act;
|
||||
velocity = new PointF();
|
||||
handler = hand;
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
handler.removeCallbacks(this);
|
||||
}
|
||||
|
||||
void start(float xv, float yv, VelocityUpdater update)
|
||||
{
|
||||
if (update == null)
|
||||
update = DefaultUpdater.instance;
|
||||
updater = update;
|
||||
velocity.x = xv;
|
||||
velocity.y = yv;
|
||||
//Log.v(TAG, String.format("pan start %f %f", velocity.x, velocity.y));
|
||||
lastSent = SystemClock.uptimeMillis();
|
||||
|
||||
handler.postDelayed(this, 50);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
long interval = SystemClock.uptimeMillis() - lastSent;
|
||||
lastSent += interval;
|
||||
double scale = (double)interval / 50.0;
|
||||
//Log.v(TAG, String.format("panning %f %d %d", scale, (int)((double)velocity.x * scale), (int)((double)velocity.y * scale)));
|
||||
if ( activity.vncCanvas.pan((int)((double)velocity.x * scale), (int)((double)velocity.y * scale)))
|
||||
{
|
||||
if (updater.updateVelocity(velocity, interval))
|
||||
{
|
||||
handler.postDelayed(this, 50);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Log.v(TAG, "Updater requests stop");
|
||||
stop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Log.v(TAG, "Panning failed");
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
55
app/src/main/java/android/androidVNC/RepeaterDialog.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.app.*;
|
||||
import android.os.*;
|
||||
import android.text.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class RepeaterDialog extends Dialog {
|
||||
private EditText _repeaterId;
|
||||
androidVNC _configurationDialog;
|
||||
|
||||
RepeaterDialog(androidVNC context) {
|
||||
super(context);
|
||||
setOwnerActivity((Activity)context);
|
||||
_configurationDialog = context;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Dialog#onCreate(android.os.Bundle)
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setTitle(R.string.repeater_dialog_title);
|
||||
|
||||
setContentView(R.layout.repeater_dialog);
|
||||
_repeaterId=(EditText)findViewById(R.id.textRepeaterInfo);
|
||||
((TextView)findViewById(R.id.textRepeaterCaption)).setText(Html.fromHtml(getContext().getString(R.string.repeater_caption)));
|
||||
((Button)findViewById(R.id.buttonSaveRepeater)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
_configurationDialog.updateRepeaterInfo(true, _repeaterId.getText().toString());
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
((Button)findViewById(R.id.buttonClearRepeater)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
_configurationDialog.updateRepeaterInfo(false, "");
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
1303
app/src/main/java/android/androidVNC/RfbProto.java
Normal file
84
app/src/main/java/android/androidVNC/SentTextBean.java
Normal file
@@ -0,0 +1,84 @@
|
||||
// This class was generated from android.androidVNC.ISentText by a tool
|
||||
// Do not edit this file directly! PLX THX
|
||||
package android.androidVNC;
|
||||
|
||||
public class SentTextBean extends com.antlersoft.android.dbimpl.IdImplementationBase implements ISentText {
|
||||
|
||||
public static final String GEN_TABLE_NAME = "SENT_TEXT";
|
||||
public static final int GEN_COUNT = 2;
|
||||
|
||||
// Field constants
|
||||
public static final String GEN_FIELD__ID = "_id";
|
||||
public static final int GEN_ID__ID = 0;
|
||||
public static final String GEN_FIELD_SENTTEXT = "SENTTEXT";
|
||||
public static final int GEN_ID_SENTTEXT = 1;
|
||||
|
||||
// SQL Command for creating the table
|
||||
public static String GEN_CREATE = "CREATE TABLE SENT_TEXT (" +
|
||||
"_id INTEGER PRIMARY KEY AUTOINCREMENT," +
|
||||
"SENTTEXT TEXT" +
|
||||
")";
|
||||
|
||||
// Members corresponding to defined fields
|
||||
private long gen__Id;
|
||||
private java.lang.String gen_sentText;
|
||||
|
||||
|
||||
public static final com.antlersoft.android.dbimpl.NewInstance<SentTextBean> GEN_NEW = new com.antlersoft.android.dbimpl.NewInstance<SentTextBean>() {
|
||||
public SentTextBean get() {
|
||||
return new SentTextBean();
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
public String Gen_tableName() { return GEN_TABLE_NAME; }
|
||||
|
||||
// Field accessors
|
||||
public long get_Id() { return gen__Id; }
|
||||
public void set_Id(long arg__Id) { gen__Id = arg__Id; }
|
||||
public java.lang.String getSentText() { return gen_sentText; }
|
||||
public void setSentText(java.lang.String arg_sentText) { gen_sentText = arg_sentText; }
|
||||
|
||||
public android.content.ContentValues Gen_getValues() {
|
||||
android.content.ContentValues values=new android.content.ContentValues();
|
||||
values.put(GEN_FIELD__ID,Long.toString(this.gen__Id));
|
||||
values.put(GEN_FIELD_SENTTEXT,this.gen_sentText);
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array that gives the column index in the cursor for each field defined
|
||||
* @param cursor Database cursor over some columns, possibly including this table
|
||||
* @return array of column indices; -1 if the column with that id is not in cursor
|
||||
*/
|
||||
public int[] Gen_columnIndices(android.database.Cursor cursor) {
|
||||
int[] result=new int[GEN_COUNT];
|
||||
result[0] = cursor.getColumnIndex(GEN_FIELD__ID);
|
||||
// Make compatible with database generated by older version of plugin with uppercase column name
|
||||
if (result[0] == -1) {
|
||||
result[0] = cursor.getColumnIndex("_ID");
|
||||
}
|
||||
result[1] = cursor.getColumnIndex(GEN_FIELD_SENTTEXT);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate one instance from a cursor
|
||||
*/
|
||||
public void Gen_populate(android.database.Cursor cursor,int[] columnIndices) {
|
||||
if ( columnIndices[GEN_ID__ID] >= 0 && ! cursor.isNull(columnIndices[GEN_ID__ID])) {
|
||||
gen__Id = cursor.getLong(columnIndices[GEN_ID__ID]);
|
||||
}
|
||||
if ( columnIndices[GEN_ID_SENTTEXT] >= 0 && ! cursor.isNull(columnIndices[GEN_ID_SENTTEXT])) {
|
||||
gen_sentText = cursor.getString(columnIndices[GEN_ID_SENTTEXT]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate one instance from a ContentValues
|
||||
*/
|
||||
public void Gen_populate(android.content.ContentValues values) {
|
||||
gen__Id = values.getAsLong(GEN_FIELD__ID);
|
||||
gen_sentText = values.getAsString(GEN_FIELD_SENTTEXT);
|
||||
}
|
||||
}
|
||||
75
app/src/main/java/android/androidVNC/Utils.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package android.androidVNC;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ActivityManager.MemoryInfo;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.text.Html;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static void showYesNoPrompt(Context _context, String title, String message, OnClickListener onYesListener, OnClickListener onNoListener) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(_context);
|
||||
builder.setTitle(title);
|
||||
builder.setIcon(android.R.drawable.ic_dialog_info); // lame icon
|
||||
builder.setMessage(message);
|
||||
builder.setCancelable(false);
|
||||
builder.setPositiveButton("Yes", onYesListener);
|
||||
builder.setNegativeButton("No", onNoListener);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private static final Intent docIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://code.google.com/p/android-vnc-viewer/wiki/Documentation"));
|
||||
|
||||
public static ActivityManager getActivityManager(Context context)
|
||||
{
|
||||
ActivityManager result = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
if (result == null)
|
||||
throw new UnsupportedOperationException("Could not retrieve ActivityManager");
|
||||
return result;
|
||||
}
|
||||
|
||||
public static MemoryInfo getMemoryInfo(Context _context) {
|
||||
MemoryInfo info = new MemoryInfo();
|
||||
getActivityManager(_context).getMemoryInfo(info);
|
||||
return info;
|
||||
}
|
||||
|
||||
public static void showDocumentation(Context c) {
|
||||
c.startActivity(docIntent);
|
||||
}
|
||||
|
||||
private static int nextNoticeID = 0;
|
||||
public static int nextNoticeID() {
|
||||
nextNoticeID++;
|
||||
return nextNoticeID;
|
||||
}
|
||||
|
||||
public static void showErrorMessage(Context _context, String message) {
|
||||
showMessage(_context, "Error!", message, android.R.drawable.ic_dialog_alert, null);
|
||||
}
|
||||
|
||||
public static void showFatalErrorMessage(final Context _context, String message) {
|
||||
showMessage(_context, "Fatal Error!", message, android.R.drawable.ic_dialog_alert, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
// ((Activity) _context).finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void showMessage(Context _context, String title, String message, int icon, DialogInterface.OnClickListener ackHandler) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(_context);
|
||||
builder.setTitle(title);
|
||||
builder.setMessage(Html.fromHtml(message));
|
||||
builder.setCancelable(false);
|
||||
builder.setPositiveButton("Acknowledged", ackHandler);
|
||||
builder.setIcon(icon);
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
1635
app/src/main/java/android/androidVNC/VncCanvas.java
Normal file
1917
app/src/main/java/android/androidVNC/VncCanvasActivity.java
Normal file
8
app/src/main/java/android/androidVNC/VncConstants.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package android.androidVNC;
|
||||
|
||||
/**
|
||||
* Keys for intent values
|
||||
*/
|
||||
public class VncConstants {
|
||||
public static final String CONNECTION = "android.androidVNC.CONNECTION";
|
||||
}
|
||||
92
app/src/main/java/android/androidVNC/VncDatabase.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class VncDatabase extends SQLiteOpenHelper {
|
||||
static final int DBV_0_2_X = 9;
|
||||
static final int DBV_0_2_4 = 10;
|
||||
static final int DBV_0_4_7 = 11;
|
||||
static final int DBV_0_5_0 = 12;
|
||||
|
||||
public final static String TAG = VncDatabase.class.toString();
|
||||
|
||||
VncDatabase(Context context)
|
||||
{
|
||||
super(context,"VncDatabase",null,DBV_0_5_0);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(AbstractConnectionBean.GEN_CREATE);
|
||||
db.execSQL(MostRecentBean.GEN_CREATE);
|
||||
db.execSQL(MetaList.GEN_CREATE);
|
||||
db.execSQL(AbstractMetaKeyBean.GEN_CREATE);
|
||||
db.execSQL(SentTextBean.GEN_CREATE);
|
||||
|
||||
db.execSQL("INSERT INTO "+MetaList.GEN_TABLE_NAME+" VALUES ( 1, 'DEFAULT')");
|
||||
}
|
||||
|
||||
private void defaultUpgrade(SQLiteDatabase db)
|
||||
{
|
||||
Log.i(TAG, "Doing default database upgrade (drop and create tables)");
|
||||
db.execSQL("DROP TABLE IF EXISTS " + AbstractConnectionBean.GEN_TABLE_NAME);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + MostRecentBean.GEN_TABLE_NAME);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + MetaList.GEN_TABLE_NAME);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + AbstractMetaKeyBean.GEN_TABLE_NAME);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + SentTextBean.GEN_TABLE_NAME);
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
|
||||
*/
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion < DBV_0_2_X)
|
||||
{
|
||||
defaultUpgrade(db);
|
||||
}
|
||||
else {
|
||||
if (oldVersion == DBV_0_2_X)
|
||||
{
|
||||
Log.i(TAG, "Doing upgrade from 9 to 10");
|
||||
db.execSQL("ALTER TABLE " + AbstractConnectionBean.GEN_TABLE_NAME + " RENAME TO OLD_" +
|
||||
AbstractConnectionBean.GEN_TABLE_NAME);
|
||||
db.execSQL(AbstractConnectionBean.GEN_CREATE);
|
||||
db.execSQL("INSERT INTO " + AbstractConnectionBean.GEN_TABLE_NAME +
|
||||
" SELECT *, 0 FROM OLD_" + AbstractConnectionBean.GEN_TABLE_NAME);
|
||||
db.execSQL("DROP TABLE OLD_" + AbstractConnectionBean.GEN_TABLE_NAME);
|
||||
oldVersion = DBV_0_2_4;
|
||||
}
|
||||
if (oldVersion == DBV_0_2_4)
|
||||
{
|
||||
Log.i(TAG,"Doing upgrade from 10 to 11");
|
||||
db.execSQL("ALTER TABLE " + AbstractConnectionBean.GEN_TABLE_NAME + " ADD COLUMN " +AbstractConnectionBean.GEN_FIELD_USERNAME+" TEXT");
|
||||
db.execSQL("ALTER TABLE " + AbstractConnectionBean.GEN_TABLE_NAME + " ADD COLUMN " +AbstractConnectionBean.GEN_FIELD_SECURECONNECTIONTYPE+" TEXT");
|
||||
db.execSQL("ALTER TABLE " + MostRecentBean.GEN_TABLE_NAME + " ADD COLUMN " + MostRecentBean.GEN_FIELD_SHOW_SPLASH_VERSION + " INTEGER");
|
||||
db.execSQL("ALTER TABLE " + MostRecentBean.GEN_TABLE_NAME + " ADD COLUMN " + MostRecentBean.GEN_FIELD_TEXT_INDEX);
|
||||
oldVersion = DBV_0_4_7;
|
||||
}
|
||||
Log.i(TAG,"Doing upgrade from 11 to 12");
|
||||
// Haven't been using SentText before, primary key handling changed so drop and recreate it
|
||||
db.execSQL("DROP TABLE IF EXISTS " + SentTextBean.GEN_TABLE_NAME);
|
||||
db.execSQL(SentTextBean.GEN_CREATE);
|
||||
db.execSQL("ALTER TABLE " + AbstractConnectionBean.GEN_TABLE_NAME + " ADD COLUMN " +AbstractConnectionBean.GEN_FIELD_SHOWZOOMBUTTONS+" INTEGER DEFAULT 1");
|
||||
db.execSQL("ALTER TABLE " + AbstractConnectionBean.GEN_TABLE_NAME + " ADD COLUMN " +AbstractConnectionBean.GEN_FIELD_DOUBLE_TAP_ACTION+" TEXT");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
112
app/src/main/java/android/androidVNC/ZlibInStream.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package android.androidVNC;
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This 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 software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// A ZlibInStream reads from a zlib.io.InputStream
|
||||
//
|
||||
|
||||
public class ZlibInStream extends InStream {
|
||||
|
||||
static final int defaultBufSize = 16384;
|
||||
|
||||
public ZlibInStream(int bufSize_) {
|
||||
bufSize = bufSize_;
|
||||
b = new byte[bufSize];
|
||||
ptr = end = ptrOffset = 0;
|
||||
inflater = new java.util.zip.Inflater();
|
||||
}
|
||||
|
||||
public ZlibInStream() { this(defaultBufSize); }
|
||||
|
||||
public void setUnderlying(InStream is, int bytesIn_) {
|
||||
underlying = is;
|
||||
bytesIn = bytesIn_;
|
||||
ptr = end = 0;
|
||||
}
|
||||
|
||||
public void reset() throws Exception {
|
||||
ptr = end = 0;
|
||||
if (underlying == null) return;
|
||||
|
||||
while (bytesIn > 0) {
|
||||
decompress();
|
||||
end = 0; // throw away any data
|
||||
}
|
||||
underlying = null;
|
||||
}
|
||||
|
||||
public int pos() { return ptrOffset + ptr; }
|
||||
|
||||
protected int overrun(int itemSize, int nItems) throws Exception {
|
||||
if (itemSize > bufSize)
|
||||
throw new Exception("ZlibInStream overrun: max itemSize exceeded");
|
||||
if (underlying == null)
|
||||
throw new Exception("ZlibInStream overrun: no underlying stream");
|
||||
|
||||
if (end - ptr != 0)
|
||||
System.arraycopy(b, ptr, b, 0, end - ptr);
|
||||
|
||||
ptrOffset += ptr;
|
||||
end -= ptr;
|
||||
ptr = 0;
|
||||
|
||||
while (end < itemSize) {
|
||||
decompress();
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end)
|
||||
nItems = end / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
// decompress() calls the decompressor once. Note that this won't
|
||||
// necessarily generate any output data - it may just consume some input
|
||||
// data. Returns false if wait is false and we would block on the underlying
|
||||
// stream.
|
||||
|
||||
private void decompress() throws Exception {
|
||||
try {
|
||||
underlying.check(1);
|
||||
int avail_in = underlying.getend() - underlying.getptr();
|
||||
if (avail_in > bytesIn)
|
||||
avail_in = bytesIn;
|
||||
|
||||
if (inflater.needsInput()) {
|
||||
inflater.setInput(underlying.getbuf(), underlying.getptr(), avail_in);
|
||||
}
|
||||
|
||||
int n = inflater.inflate(b, end, bufSize - end);
|
||||
|
||||
end += n;
|
||||
if (inflater.needsInput()) {
|
||||
bytesIn -= avail_in;
|
||||
underlying.setptr(underlying.getptr() + avail_in);
|
||||
}
|
||||
} catch (java.util.zip.DataFormatException e) {
|
||||
throw new Exception("ZlibInStream: inflate failed");
|
||||
}
|
||||
}
|
||||
|
||||
private InStream underlying;
|
||||
private int bufSize;
|
||||
private int ptrOffset;
|
||||
private java.util.zip.Inflater inflater;
|
||||
private int bytesIn;
|
||||
}
|
||||
186
app/src/main/java/android/androidVNC/ZoomScaling.java
Normal file
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package android.androidVNC;
|
||||
|
||||
import android.graphics.*;
|
||||
import android.widget.ImageView.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
class ZoomScaling extends AbstractScaling {
|
||||
|
||||
static final String TAG = "ZoomScaling";
|
||||
|
||||
private Matrix matrix;
|
||||
int canvasXOffset;
|
||||
int canvasYOffset;
|
||||
float scaling;
|
||||
float minimumScale;
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param scaleType
|
||||
*/
|
||||
public ZoomScaling() {
|
||||
super(R.id.itemZoomable, ScaleType.MATRIX);
|
||||
matrix = new Matrix();
|
||||
scaling = 1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#getDefaultHandlerId()
|
||||
*/
|
||||
@Override
|
||||
int getDefaultHandlerId() {
|
||||
return R.id.itemInputTouchPanZoomMouse;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#isAbleToPan()
|
||||
*/
|
||||
@Override
|
||||
boolean isAbleToPan() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#isValidInputMode(int)
|
||||
*/
|
||||
@Override
|
||||
boolean isValidInputMode(int mode) {
|
||||
return mode != R.id.itemInputFitToScreen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call after scaling and matrix have been changed to resolve scrolling
|
||||
* @param activity
|
||||
*/
|
||||
private void resolveZoom(VncCanvasActivity activity)
|
||||
{
|
||||
activity.vncCanvas.scrollToAbsolute();
|
||||
activity.vncCanvas.pan(0,0);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#zoomIn(android.androidVNC.VncCanvasActivity)
|
||||
*/
|
||||
@Override
|
||||
void zoomIn(VncCanvasActivity activity) {
|
||||
resetMatrix();
|
||||
standardizeScaling();
|
||||
scaling += 0.25;
|
||||
if (scaling > 4.0)
|
||||
{
|
||||
scaling = (float)4.0;
|
||||
activity.zoomer.setIsZoomInEnabled(false);
|
||||
}
|
||||
activity.zoomer.setIsZoomOutEnabled(true);
|
||||
matrix.postScale(scaling, scaling);
|
||||
//Log.v(TAG,String.format("before set matrix scrollx = %d scrolly = %d", activity.vncCanvas.getScrollX(), activity.vncCanvas.getScrollY()));
|
||||
activity.vncCanvas.setImageMatrix(matrix);
|
||||
resolveZoom(activity);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#getScale()
|
||||
*/
|
||||
@Override
|
||||
float getScale() {
|
||||
return scaling;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#zoomOut(android.androidVNC.VncCanvasActivity)
|
||||
*/
|
||||
@Override
|
||||
void zoomOut(VncCanvasActivity activity) {
|
||||
resetMatrix();
|
||||
standardizeScaling();
|
||||
scaling -= 0.25;
|
||||
if (scaling < minimumScale)
|
||||
{
|
||||
scaling = minimumScale;
|
||||
activity.zoomer.setIsZoomOutEnabled(false);
|
||||
}
|
||||
activity.zoomer.setIsZoomInEnabled(true);
|
||||
matrix.postScale(scaling, scaling);
|
||||
//Log.v(TAG,String.format("before set matrix scrollx = %d scrolly = %d", activity.vncCanvas.getScrollX(), activity.vncCanvas.getScrollY()));
|
||||
activity.vncCanvas.setImageMatrix(matrix);
|
||||
//Log.v(TAG,String.format("after set matrix scrollx = %d scrolly = %d", activity.vncCanvas.getScrollX(), activity.vncCanvas.getScrollY()));
|
||||
resolveZoom(activity);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#adjust(android.androidVNC.VncCanvasActivity, float, float, float)
|
||||
*/
|
||||
@Override
|
||||
void adjust(VncCanvasActivity activity, float scaleFactor, float fx,
|
||||
float fy) {
|
||||
float newScale = scaleFactor * scaling;
|
||||
if (scaleFactor < 1)
|
||||
{
|
||||
if (newScale < minimumScale)
|
||||
{
|
||||
newScale = minimumScale;
|
||||
activity.zoomer.setIsZoomOutEnabled(false);
|
||||
}
|
||||
activity.zoomer.setIsZoomInEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (newScale > 4)
|
||||
{
|
||||
newScale = 4;
|
||||
activity.zoomer.setIsZoomInEnabled(false);
|
||||
}
|
||||
activity.zoomer.setIsZoomOutEnabled(true);
|
||||
}
|
||||
// ax is the absolute x of the focus
|
||||
int xPan = activity.vncCanvas.absoluteXPosition;
|
||||
float ax = (fx / scaling) + xPan;
|
||||
float newXPan = (scaling * xPan - scaling * ax + newScale * ax)/newScale;
|
||||
int yPan = activity.vncCanvas.absoluteYPosition;
|
||||
float ay = (fy / scaling) + yPan;
|
||||
float newYPan = (scaling * yPan - scaling * ay + newScale * ay)/newScale;
|
||||
resetMatrix();
|
||||
scaling = newScale;
|
||||
matrix.postScale(scaling, scaling);
|
||||
activity.vncCanvas.setImageMatrix(matrix);
|
||||
resolveZoom(activity);
|
||||
activity.vncCanvas.pan((int)(newXPan - xPan), (int)(newYPan - yPan));
|
||||
}
|
||||
|
||||
private void resetMatrix()
|
||||
{
|
||||
matrix.reset();
|
||||
matrix.preTranslate(canvasXOffset, canvasYOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set scaling to one of the clicks on the zoom scale
|
||||
*/
|
||||
private void standardizeScaling()
|
||||
{
|
||||
scaling = ((float)((int)(scaling * 4))) / 4;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.androidVNC.AbstractScaling#setScaleTypeForActivity(android.androidVNC.VncCanvasActivity)
|
||||
*/
|
||||
@Override
|
||||
void setScaleTypeForActivity(VncCanvasActivity activity) {
|
||||
super.setScaleTypeForActivity(activity);
|
||||
scaling = (float)1.0;
|
||||
minimumScale = activity.vncCanvas.bitmapData.getMinimumScale();
|
||||
canvasXOffset = -activity.vncCanvas.getCenteredXOffset();
|
||||
canvasYOffset = -activity.vncCanvas.getCenteredYOffset();
|
||||
resetMatrix();
|
||||
activity.vncCanvas.setImageMatrix(matrix);
|
||||
// Reset the pan position to (0,0)
|
||||
resolveZoom(activity);
|
||||
}
|
||||
|
||||
}
|
||||
379
app/src/main/java/android/androidVNC/androidVNC.java
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* This 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 software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// androidVNC is the Activity for setting VNC server IP and port.
|
||||
//
|
||||
|
||||
package android.androidVNC;
|
||||
|
||||
import android.app.*;
|
||||
import android.app.ActivityManager.*;
|
||||
import android.content.*;
|
||||
import android.database.sqlite.*;
|
||||
import android.os.*;
|
||||
import android.support.v7.app.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import java.util.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
public class androidVNC extends AppCompatActivity {
|
||||
private EditText ipText;
|
||||
private EditText portText;
|
||||
private EditText passwordText;
|
||||
private Button goButton;
|
||||
private TextView repeaterText;
|
||||
private RadioGroup groupForceFullScreen;
|
||||
private Spinner colorSpinner;
|
||||
private Spinner spinnerConnection;
|
||||
private VncDatabase database;
|
||||
private ConnectionBean selected;
|
||||
private EditText textNickname;
|
||||
private EditText textUsername;
|
||||
private CheckBox checkboxKeepPassword;
|
||||
private CheckBox checkboxLocalCursor;
|
||||
private boolean repeaterTextSet;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
|
||||
super.onCreate(icicle);
|
||||
setContentView(R.layout.androidvncmain);
|
||||
|
||||
ipText = (EditText) findViewById(R.id.textIP);
|
||||
portText = (EditText) findViewById(R.id.textPORT);
|
||||
passwordText = (EditText) findViewById(R.id.textPASSWORD);
|
||||
textNickname = (EditText) findViewById(R.id.textNickname);
|
||||
textUsername = (EditText) findViewById(R.id.textUsername);
|
||||
goButton = (Button) findViewById(R.id.buttonGO);
|
||||
((Button) findViewById(R.id.buttonRepeater)).setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showDialog(R.layout.repeater_dialog);
|
||||
}
|
||||
});
|
||||
((Button)findViewById(R.id.buttonImportExport)).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showDialog(R.layout.importexport);
|
||||
}
|
||||
});
|
||||
colorSpinner = (Spinner)findViewById(R.id.colorformat);
|
||||
COLORMODEL[] models=COLORMODEL.values();
|
||||
ArrayAdapter<COLORMODEL> colorSpinnerAdapter = new ArrayAdapter<COLORMODEL>(this, android.R.layout.simple_spinner_item, models);
|
||||
groupForceFullScreen = (RadioGroup)findViewById(R.id.groupForceFullScreen);
|
||||
checkboxKeepPassword = (CheckBox)findViewById(R.id.checkboxKeepPassword);
|
||||
checkboxLocalCursor = (CheckBox)findViewById(R.id.checkboxUseLocalCursor);
|
||||
colorSpinner.setAdapter(colorSpinnerAdapter);
|
||||
colorSpinner.setSelection(0);
|
||||
spinnerConnection = (Spinner)findViewById(R.id.spinnerConnection);
|
||||
spinnerConnection.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> ad, View view, int itemIndex, long id) {
|
||||
selected = (ConnectionBean)ad.getSelectedItem();
|
||||
updateViewFromSelected();
|
||||
}
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> ad) {
|
||||
selected = null;
|
||||
}
|
||||
});
|
||||
spinnerConnection.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.widget.AdapterView.OnItemLongClickListener#onItemLongClick(android.widget.AdapterView, android.view.View, int, long)
|
||||
*/
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
|
||||
int arg2, long arg3) {
|
||||
spinnerConnection.setSelection(arg2);
|
||||
selected = (ConnectionBean)spinnerConnection.getItemAtPosition(arg2);
|
||||
canvasStart();
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
repeaterText = (TextView)findViewById(R.id.textRepeaterId);
|
||||
goButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
canvasStart();
|
||||
}
|
||||
});
|
||||
|
||||
database = new VncDatabase(this);
|
||||
}
|
||||
|
||||
protected void onDestroy() {
|
||||
database.close();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Activity#onCreateDialog(int)
|
||||
*/
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
if (id == R.layout.importexport)
|
||||
return new ImportExportDialog(this);
|
||||
else
|
||||
return new RepeaterDialog(this);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
|
||||
*/
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.androidvncmenu,menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Activity#onMenuOpened(int, android.view.Menu)
|
||||
*/
|
||||
@Override
|
||||
public boolean onMenuOpened(int featureId, Menu menu) {
|
||||
menu.findItem(R.id.itemDeleteConnection).setEnabled(selected!=null && ! selected.isNew());
|
||||
menu.findItem(R.id.itemSaveAsCopy).setEnabled(selected!=null && ! selected.isNew());
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
|
||||
*/
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId())
|
||||
{
|
||||
case R.id.itemSaveAsCopy :
|
||||
if (selected.getNickname().equals(textNickname.getText().toString()))
|
||||
textNickname.setText("Copy of "+selected.getNickname());
|
||||
updateSelectedFromView();
|
||||
selected.set_Id(0);
|
||||
saveAndWriteRecent();
|
||||
arriveOnPage();
|
||||
break;
|
||||
case R.id.itemDeleteConnection :
|
||||
Utils.showYesNoPrompt(this, "Delete?", "Delete " + selected.getNickname() + "?",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int i)
|
||||
{
|
||||
selected.Gen_delete(database.getWritableDatabase());
|
||||
arriveOnPage();
|
||||
}
|
||||
}, null);
|
||||
break;
|
||||
case R.id.itemOpenDoc :
|
||||
Utils.showDocumentation(this);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateViewFromSelected() {
|
||||
if (selected==null)
|
||||
return;
|
||||
ipText.setText(selected.getAddress());
|
||||
portText.setText(Integer.toString(selected.getPort()));
|
||||
if (selected.getKeepPassword() || selected.getPassword().length()>0) {
|
||||
passwordText.setText(selected.getPassword());
|
||||
}
|
||||
groupForceFullScreen.check(selected.getForceFull()==BitmapImplHint.AUTO ? R.id.radioForceFullScreenAuto : (selected.getForceFull() == BitmapImplHint.FULL ? R.id.radioForceFullScreenOn : R.id.radioForceFullScreenOff));
|
||||
checkboxKeepPassword.setChecked(selected.getKeepPassword());
|
||||
checkboxLocalCursor.setChecked(selected.getUseLocalCursor());
|
||||
textNickname.setText(selected.getNickname());
|
||||
textUsername.setText(selected.getUserName());
|
||||
COLORMODEL cm = COLORMODEL.valueOf(selected.getColorModel());
|
||||
COLORMODEL[] colors=COLORMODEL.values();
|
||||
for (int i=0; i<colors.length; ++i)
|
||||
{
|
||||
if (colors[i] == cm) {
|
||||
colorSpinner.setSelection(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateRepeaterInfo(selected.getUseRepeater(), selected.getRepeaterId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when changing view to match selected connection or from
|
||||
* Repeater dialog to update the repeater information shown.
|
||||
* @param repeaterId If null or empty, show text for not using repeater
|
||||
*/
|
||||
void updateRepeaterInfo(boolean useRepeater, String repeaterId)
|
||||
{
|
||||
if (useRepeater)
|
||||
{
|
||||
repeaterText.setText(repeaterId);
|
||||
repeaterTextSet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
repeaterText.setText(getText(R.string.repeater_empty_text));
|
||||
repeaterTextSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSelectedFromView() {
|
||||
if (selected==null) {
|
||||
return;
|
||||
}
|
||||
selected.setAddress(ipText.getText().toString());
|
||||
try
|
||||
{
|
||||
selected.setPort(Integer.parseInt(portText.getText().toString()));
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
|
||||
}
|
||||
selected.setNickname(textNickname.getText().toString());
|
||||
selected.setUserName(textUsername.getText().toString());
|
||||
selected.setForceFull(groupForceFullScreen.getCheckedRadioButtonId()==R.id.radioForceFullScreenAuto ? BitmapImplHint.AUTO : (groupForceFullScreen.getCheckedRadioButtonId()==R.id.radioForceFullScreenOn ? BitmapImplHint.FULL : BitmapImplHint.TILE));
|
||||
selected.setPassword(passwordText.getText().toString());
|
||||
selected.setKeepPassword(checkboxKeepPassword.isChecked());
|
||||
selected.setUseLocalCursor(checkboxLocalCursor.isChecked());
|
||||
selected.setColorModel(((COLORMODEL)colorSpinner.getSelectedItem()).nameString());
|
||||
if (repeaterTextSet)
|
||||
{
|
||||
selected.setRepeaterId(repeaterText.getText().toString());
|
||||
selected.setUseRepeater(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
selected.setUseRepeater(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
arriveOnPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the object representing the app global state in the database, or null
|
||||
* if the object hasn't been set up yet
|
||||
* @param db App's database -- only needs to be readable
|
||||
* @return Object representing the single persistent instance of MostRecentBean, which
|
||||
* is the app's global state
|
||||
*/
|
||||
static MostRecentBean getMostRecent(SQLiteDatabase db)
|
||||
{
|
||||
ArrayList<MostRecentBean> recents = new ArrayList<MostRecentBean>(1);
|
||||
MostRecentBean.getAll(db, MostRecentBean.GEN_TABLE_NAME, recents, MostRecentBean.GEN_NEW);
|
||||
if (recents.size() == 0)
|
||||
return null;
|
||||
return recents.get(0);
|
||||
}
|
||||
|
||||
void arriveOnPage() {
|
||||
ArrayList<ConnectionBean> connections=new ArrayList<ConnectionBean>();
|
||||
ConnectionBean.getAll(database.getReadableDatabase(), ConnectionBean.GEN_TABLE_NAME, connections, ConnectionBean.newInstance);
|
||||
Collections.sort(connections);
|
||||
connections.add(0, new ConnectionBean());
|
||||
int connectionIndex=0;
|
||||
if ( connections.size()>1)
|
||||
{
|
||||
MostRecentBean mostRecent = getMostRecent(database.getReadableDatabase());
|
||||
if (mostRecent != null)
|
||||
{
|
||||
for ( int i=1; i<connections.size(); ++i)
|
||||
{
|
||||
if (connections.get(i).get_Id() == mostRecent.getConnectionId())
|
||||
{
|
||||
connectionIndex=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
spinnerConnection.setAdapter(new ArrayAdapter<ConnectionBean>(this,android.R.layout.simple_spinner_item,
|
||||
connections.toArray(new ConnectionBean[connections.size()])));
|
||||
spinnerConnection.setSelection(connectionIndex,false);
|
||||
selected=connections.get(connectionIndex);
|
||||
updateViewFromSelected();
|
||||
IntroTextDialog.showIntroTextIfNecessary(this, database);
|
||||
}
|
||||
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
if ( selected == null ) {
|
||||
return;
|
||||
}
|
||||
updateSelectedFromView();
|
||||
selected.save(database.getWritableDatabase());
|
||||
}
|
||||
|
||||
VncDatabase getDatabaseHelper()
|
||||
{
|
||||
return database;
|
||||
}
|
||||
|
||||
private void canvasStart() {
|
||||
if (selected == null) return;
|
||||
MemoryInfo info = Utils.getMemoryInfo(this);
|
||||
if (info.lowMemory) {
|
||||
// Low Memory situation. Prompt.
|
||||
Utils.showYesNoPrompt(this, "Continue?", "Android reports low system memory.\nContinue with VNC connection?", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
vnc();
|
||||
}
|
||||
}, null);
|
||||
} else
|
||||
vnc();
|
||||
}
|
||||
|
||||
private void saveAndWriteRecent()
|
||||
{
|
||||
SQLiteDatabase db = database.getWritableDatabase();
|
||||
db.beginTransaction();
|
||||
try
|
||||
{
|
||||
selected.save(db);
|
||||
MostRecentBean mostRecent = getMostRecent(db);
|
||||
if (mostRecent == null)
|
||||
{
|
||||
mostRecent = new MostRecentBean();
|
||||
mostRecent.setConnectionId(selected.get_Id());
|
||||
mostRecent.Gen_insert(db);
|
||||
}
|
||||
else
|
||||
{
|
||||
mostRecent.setConnectionId(selected.get_Id());
|
||||
mostRecent.Gen_update(db);
|
||||
}
|
||||
db.setTransactionSuccessful();
|
||||
}
|
||||
finally
|
||||
{
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
private void vnc() {
|
||||
updateSelectedFromView();
|
||||
saveAndWriteRecent();
|
||||
Intent intent = new Intent(this, VncCanvasActivity.class);
|
||||
intent.putExtra(VncConstants.CONNECTION,selected.Gen_getValues());
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
class BCActivityManagerDefault implements IBCActivityManager {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCActivityManager#getMemoryClass(android.app.ActivityManager)
|
||||
*/
|
||||
@Override
|
||||
public int getMemoryClass(ActivityManager am) {
|
||||
return 16;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
public class BCActivityManagerV5 implements IBCActivityManager {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCActivityManager#getMemoryClass(android.app.ActivityManager)
|
||||
*/
|
||||
@Override
|
||||
public int getMemoryClass(ActivityManager am) {
|
||||
return am.getMemoryClass();
|
||||
}
|
||||
|
||||
}
|
||||
255
app/src/main/java/com/antlersoft/android/bc/BCFactory.java
Normal file
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Create interface implementations appropriate to the current version of the SDK;
|
||||
* implementations can allow use of higher-level SDK calls in .apk's that will still run
|
||||
* on lower-level SDK's
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
public class BCFactory {
|
||||
|
||||
private static BCFactory _theInstance = new BCFactory();
|
||||
|
||||
private IBCActivityManager bcActivityManager;
|
||||
private IBCGestureDetector bcGestureDetector;
|
||||
private IBCHaptic bcHaptic;
|
||||
private IBCMotionEvent bcMotionEvent;
|
||||
private IBCStorageContext bcStorageContext;
|
||||
|
||||
/**
|
||||
* This is here so checking the static doesn't get optimized away;
|
||||
* note we can't use SDK_INT because that is too new
|
||||
* @return sdk version
|
||||
*/
|
||||
int getSdkVersion()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Integer.parseInt(android.os.Build.VERSION.SDK);
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the implementation of IBCActivityManager appropriate for this SDK level
|
||||
* @return
|
||||
*/
|
||||
public IBCActivityManager getBCActivityManager()
|
||||
{
|
||||
if (bcActivityManager == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (bcActivityManager == null)
|
||||
{
|
||||
if (getSdkVersion() >= 5)
|
||||
{
|
||||
try
|
||||
{
|
||||
bcActivityManager = (IBCActivityManager)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCActivityManagerV5").newInstance();
|
||||
}
|
||||
catch (Exception ie)
|
||||
{
|
||||
bcActivityManager = new BCActivityManagerDefault();
|
||||
throw new RuntimeException("Error instantiating", ie);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bcActivityManager = new BCActivityManagerDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bcActivityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the implementation of IBCGestureDetector appropriate for this SDK level
|
||||
*
|
||||
* Since we dropped support of SDK levels < 3, there is only one version at the moment.
|
||||
* @return
|
||||
*/
|
||||
public IBCGestureDetector getBCGestureDetector()
|
||||
{
|
||||
if (bcGestureDetector == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (bcGestureDetector == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
bcGestureDetector = (IBCGestureDetector)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCGestureDetectorDefault").newInstance();
|
||||
}
|
||||
catch (Exception ie)
|
||||
{
|
||||
throw new RuntimeException("Error instantiating", ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bcGestureDetector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the implementation of IBCHaptic appropriate for this SDK level
|
||||
*
|
||||
* Since we dropped support of SDK levels prior to 3, there is only one version at the moment.
|
||||
* @return
|
||||
*/
|
||||
public IBCHaptic getBCHaptic()
|
||||
{
|
||||
if (bcHaptic == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (bcHaptic == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
bcHaptic = (IBCHaptic)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCHapticDefault").newInstance();
|
||||
}
|
||||
catch (Exception ie)
|
||||
{
|
||||
throw new RuntimeException("Error instantiating", ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bcHaptic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the implementation of IBCMotionEvent appropriate for this SDK level
|
||||
* @return
|
||||
*/
|
||||
public IBCMotionEvent getBCMotionEvent()
|
||||
{
|
||||
if (bcMotionEvent == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (bcMotionEvent == null)
|
||||
{
|
||||
if (getSdkVersion() >= 5)
|
||||
{
|
||||
try
|
||||
{
|
||||
bcMotionEvent = (IBCMotionEvent)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCMotionEvent5").newInstance();
|
||||
}
|
||||
catch (Exception ie)
|
||||
{
|
||||
throw new RuntimeException("Error instantiating", ie);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
bcMotionEvent = (IBCMotionEvent)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCMotionEvent4").newInstance();
|
||||
}
|
||||
catch (Exception ie)
|
||||
{
|
||||
throw new RuntimeException("Error instantiating", ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bcMotionEvent;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static private Class[] scaleDetectorConstructorArgs = new Class[] { Context.class, OnScaleGestureListener.class };
|
||||
|
||||
/**
|
||||
* Return an instance of an implementation of {@link IBCScaleGestureDetector} appropriate to the SDK of this device.
|
||||
* This will work very much like android.view.ScaleGestureDetector on SDK >= 5. For previous
|
||||
* SDK versions, it is a dummy implementation that does nothing and will never call the listener.
|
||||
* <p>
|
||||
* Note that unlike the other methods in this class, the returned interface instance is not
|
||||
* stateless.
|
||||
* @param context The context to which the detector is applied
|
||||
* @param listener The listener to which the implementation will send scale events
|
||||
* @return The gesture detector
|
||||
*/
|
||||
public IBCScaleGestureDetector getScaleGestureDetector(Context context, OnScaleGestureListener listener)
|
||||
{
|
||||
IBCScaleGestureDetector result;
|
||||
|
||||
if (getSdkVersion() >= 5)
|
||||
{
|
||||
try {
|
||||
result = (IBCScaleGestureDetector)getClass().getClassLoader().
|
||||
loadClass("com.antlersoft.android.bc.ScaleGestureDetector").
|
||||
getConstructor(scaleDetectorConstructorArgs).newInstance(new Object[] { context, listener });
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error instantiating ScaleGestureDetector", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new DummyScaleGestureDetector();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return An implementation of IBCStorageContext appropriate for the running Android release
|
||||
*/
|
||||
public IBCStorageContext getStorageContext()
|
||||
{
|
||||
if (bcStorageContext == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (bcStorageContext == null)
|
||||
{
|
||||
if (getSdkVersion() >= 8)
|
||||
{
|
||||
try
|
||||
{
|
||||
bcStorageContext = (IBCStorageContext)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCStorageContext8").newInstance();
|
||||
}
|
||||
catch (Exception ie)
|
||||
{
|
||||
throw new RuntimeException("Error instantiating", ie);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
bcStorageContext = (IBCStorageContext)getClass().getClassLoader().loadClass("com.antlersoft.android.bc.BCStorageContext7").newInstance();
|
||||
}
|
||||
catch (Exception ie)
|
||||
{
|
||||
throw new RuntimeException("Error instantiating", ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bcStorageContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the only instance of this class, which manages the SDK specific interface
|
||||
* implementations
|
||||
* @return Factory instance
|
||||
*/
|
||||
public static BCFactory getInstance()
|
||||
{
|
||||
return _theInstance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.GestureDetector.OnGestureListener;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
public class BCGestureDetectorDefault implements IBCGestureDetector {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCGestureDetector#createGestureDetector(android.content.Context, android.view.GestureDetector.OnGestureListener)
|
||||
*/
|
||||
@Override
|
||||
public GestureDetector createGestureDetector(Context context,
|
||||
OnGestureListener listener) {
|
||||
return new GestureDetector(context, listener);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
|
||||
/**
|
||||
* Implementation for SDK version >= 3
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
class BCHapticDefault implements IBCHaptic {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCHaptic#performLongPressHaptic(android.view.View)
|
||||
*/
|
||||
@Override
|
||||
public boolean performLongPressHaptic(View v) {
|
||||
return v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING|HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
|
||||
);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCHaptic#setIsHapticEnabled(android.view.View, boolean)
|
||||
*/
|
||||
/*
|
||||
* @Override
|
||||
public boolean setIsHapticEnabled(View v, boolean enabled) {
|
||||
return v.setHapticFeedbackEnabled(hapticFeedbackEnabled)
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* Pre-sdk 5 version; add fake multi-touch sensing later?
|
||||
*
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class BCMotionEvent4 implements IBCMotionEvent {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCMotionEvent#getPointerCount(android.view.MotionEvent)
|
||||
*/
|
||||
@Override
|
||||
public int getPointerCount(MotionEvent evt) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class BCMotionEvent5 implements IBCMotionEvent {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCMotionEvent#getPointerCount(android.view.MotionEvent)
|
||||
*/
|
||||
@Override
|
||||
public int getPointerCount(MotionEvent evt) {
|
||||
return evt.getPointerCount();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2011 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import android.os.Environment;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
public class BCStorageContext7 implements IBCStorageContext {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCStorageContext#getExternalStorageDir(android.content.Context, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public File getExternalStorageDir(Context context, String type) {
|
||||
File f = Environment.getExternalStorageDirectory();
|
||||
f = new File(f, "Android/data/android.androidVNC/files");
|
||||
if (type != null)
|
||||
f=new File(f, type);
|
||||
f.mkdirs();
|
||||
return f;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class BCStorageContext8 implements IBCStorageContext {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCStorageContext#getExternalStorageDir(android.content.Context, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public File getExternalStorageDir(Context context, String type) {
|
||||
return context.getExternalFilesDir(type);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* MODIFIED FOR ANTLERSOFT
|
||||
*
|
||||
* Changes for antlersoft/ vnc viewer for android
|
||||
*
|
||||
* Copyright (C) 2010 Michael A. MacDonald
|
||||
*
|
||||
* This 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 software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* Implementation of scale gesture detector interface for devices without multi-touch support; does nothing
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
class DummyScaleGestureDetector implements IBCScaleGestureDetector {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getCurrentSpan()
|
||||
*/
|
||||
@Override
|
||||
public float getCurrentSpan() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getEventTime()
|
||||
*/
|
||||
@Override
|
||||
public long getEventTime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getFocusX()
|
||||
*/
|
||||
@Override
|
||||
public float getFocusX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getFocusY()
|
||||
*/
|
||||
@Override
|
||||
public float getFocusY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getPreviousSpan()
|
||||
*/
|
||||
@Override
|
||||
public float getPreviousSpan() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getScaleFactor()
|
||||
*/
|
||||
@Override
|
||||
public float getScaleFactor() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getTimeDelta()
|
||||
*/
|
||||
@Override
|
||||
public long getTimeDelta() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#isInProgress()
|
||||
*/
|
||||
@Override
|
||||
public boolean isInProgress() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#onTouchEvent(android.view.MotionEvent)
|
||||
*/
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
public interface IBCActivityManager {
|
||||
public int getMemoryClass(ActivityManager am);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.GestureDetector;
|
||||
|
||||
/**
|
||||
* Create a gesture detector in a version friendly way, avoiding incompatible API on older version
|
||||
* and deprecated API on newer version
|
||||
*
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
public interface IBCGestureDetector {
|
||||
public GestureDetector createGestureDetector(Context context, GestureDetector.OnGestureListener listener);
|
||||
}
|
||||
20
app/src/main/java/com/antlersoft/android/bc/IBCHaptic.java
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Access the Haptic interfaces added in version 3 without breaking compatibility
|
||||
* @author Michael A. MacDonald
|
||||
*/
|
||||
public interface IBCHaptic {
|
||||
public boolean performLongPressHaptic(View v);
|
||||
/**
|
||||
* Set whether haptic feedback is enabled on the view
|
||||
* @param enabled
|
||||
* @return Old value of setting
|
||||
*/
|
||||
//public boolean setIsHapticEnabled(View v, boolean enabled);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* Access to SDK-dependent features of MotionEvent
|
||||
*
|
||||
* @see android.view.MotionEvent
|
||||
*
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
public interface IBCMotionEvent {
|
||||
/**
|
||||
* Obtain the number of pointers active in the event
|
||||
* @see android.view.MotionEvent#getPointerCount()
|
||||
* @param evt
|
||||
* @return number of pointers
|
||||
*/
|
||||
int getPointerCount(MotionEvent evt);
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* MODIFIED FOR ANTLERSOFT
|
||||
*
|
||||
* Changes for antlersoft/ vnc viewer for android
|
||||
*
|
||||
* Copyright (C) 2010 Michael A. MacDonald
|
||||
*
|
||||
* This 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 software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
|
||||
/**
|
||||
* Backwards-compatibility interface to the android.view.ScaleGestureDetector introduced in Android SDK 8.
|
||||
*
|
||||
* This will be a working implementation of devices with SDK >= 5 (since I backported ScaleGestureDetector
|
||||
* to 5) and a dummy implementation for older devices.
|
||||
*
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
public interface IBCScaleGestureDetector {
|
||||
|
||||
public abstract boolean onTouchEvent(MotionEvent event);
|
||||
|
||||
/**
|
||||
* Returns {@code true} if a two-finger scale gesture is in progress.
|
||||
* @return {@code true} if a scale gesture is in progress, {@code false} otherwise.
|
||||
*/
|
||||
public abstract boolean isInProgress();
|
||||
|
||||
/**
|
||||
* Get the X coordinate of the current gesture's focal point.
|
||||
* If a gesture is in progress, the focal point is directly between
|
||||
* the two pointers forming the gesture.
|
||||
* If a gesture is ending, the focal point is the location of the
|
||||
* remaining pointer on the screen.
|
||||
* If {@link #isInProgress()} would return false, the result of this
|
||||
* function is undefined.
|
||||
*
|
||||
* @return X coordinate of the focal point in pixels.
|
||||
*/
|
||||
public abstract float getFocusX();
|
||||
|
||||
/**
|
||||
* Get the Y coordinate of the current gesture's focal point.
|
||||
* If a gesture is in progress, the focal point is directly between
|
||||
* the two pointers forming the gesture.
|
||||
* If a gesture is ending, the focal point is the location of the
|
||||
* remaining pointer on the screen.
|
||||
* If {@link #isInProgress()} would return false, the result of this
|
||||
* function is undefined.
|
||||
*
|
||||
* @return Y coordinate of the focal point in pixels.
|
||||
*/
|
||||
public abstract float getFocusY();
|
||||
|
||||
/**
|
||||
* Return the current distance between the two pointers forming the
|
||||
* gesture in progress.
|
||||
*
|
||||
* @return Distance between pointers in pixels.
|
||||
*/
|
||||
public abstract float getCurrentSpan();
|
||||
|
||||
/**
|
||||
* Return the previous distance between the two pointers forming the
|
||||
* gesture in progress.
|
||||
*
|
||||
* @return Previous distance between pointers in pixels.
|
||||
*/
|
||||
public abstract float getPreviousSpan();
|
||||
|
||||
/**
|
||||
* Return the scaling factor from the previous scale event to the current
|
||||
* event. This value is defined as
|
||||
* ({@link #getCurrentSpan()} / {@link #getPreviousSpan()}).
|
||||
*
|
||||
* @return The current scaling factor.
|
||||
*/
|
||||
public abstract float getScaleFactor();
|
||||
|
||||
/**
|
||||
* Return the time difference in milliseconds between the previous
|
||||
* accepted scaling event and the current scaling event.
|
||||
*
|
||||
* @return Time difference since the last scaling event in milliseconds.
|
||||
*/
|
||||
public abstract long getTimeDelta();
|
||||
|
||||
/**
|
||||
* Return the event time of the current event being processed.
|
||||
*
|
||||
* @return Current event time in milliseconds.
|
||||
*/
|
||||
public abstract long getEventTime();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Provides a way to access the directory on external storage as returned by
|
||||
* Context.getExternal... added in API 8 that will work with earlier API releases.
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
public interface IBCStorageContext {
|
||||
/**
|
||||
*
|
||||
* @param context Context within the application with which the storage will be associated
|
||||
* @param type May be null; if specified, references a sub-directory within the base directory
|
||||
* for the app in the external storage
|
||||
* @return File representing abstract path of storage directory; refer to android.os.Environment to
|
||||
* see if the path is actually accessible
|
||||
*/
|
||||
public File getExternalStorageDir(Context context, String type);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* MODIFIED FOR ANTLERSOFT
|
||||
*
|
||||
* Changes for antlersoft/ vnc viewer for android
|
||||
*
|
||||
* Copyright (C) 2010 Michael A. MacDonald
|
||||
*
|
||||
* This 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 software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
|
||||
/**
|
||||
* The listener for receiving notifications when gestures occur.
|
||||
* If you want to listen for all the different gestures then implement
|
||||
* this interface. If you only want to listen for a subset it might
|
||||
* be easier to extend {@link SimpleOnScaleGestureListener}.
|
||||
*
|
||||
* An application will receive events in the following order:
|
||||
* <ul>
|
||||
* <li>One {@link OnScaleGestureListener#onScaleBegin(ScaleGestureDetector)}
|
||||
* <li>Zero or more {@link OnScaleGestureListener#onScale(ScaleGestureDetector)}
|
||||
* <li>One {@link OnScaleGestureListener#onScaleEnd(ScaleGestureDetector)}
|
||||
* </ul>
|
||||
*/
|
||||
public interface OnScaleGestureListener {
|
||||
/**
|
||||
* Responds to scaling events for a gesture in progress.
|
||||
* Reported by pointer motion.
|
||||
*
|
||||
* @param detector The detector reporting the event - use this to
|
||||
* retrieve extended info about event state.
|
||||
* @return Whether or not the detector should consider this event
|
||||
* as handled. If an event was not handled, the detector
|
||||
* will continue to accumulate movement until an event is
|
||||
* handled. This can be useful if an application, for example,
|
||||
* only wants to update scaling factors if the change is
|
||||
* greater than 0.01.
|
||||
*/
|
||||
public boolean onScale(IBCScaleGestureDetector detector);
|
||||
|
||||
/**
|
||||
* Responds to the beginning of a scaling gesture. Reported by
|
||||
* new pointers going down.
|
||||
*
|
||||
* @param detector The detector reporting the event - use this to
|
||||
* retrieve extended info about event state.
|
||||
* @return Whether or not the detector should continue recognizing
|
||||
* this gesture. For example, if a gesture is beginning
|
||||
* with a focal point outside of a region where it makes
|
||||
* sense, onScaleBegin() may return false to ignore the
|
||||
* rest of the gesture.
|
||||
*/
|
||||
public boolean onScaleBegin(IBCScaleGestureDetector detector);
|
||||
|
||||
/**
|
||||
* Responds to the end of a scale gesture. Reported by existing
|
||||
* pointers going up.
|
||||
*
|
||||
* Once a scale has ended, {@link ScaleGestureDetector#getFocusX()}
|
||||
* and {@link ScaleGestureDetector#getFocusY()} will return the location
|
||||
* of the pointer remaining on the screen.
|
||||
*
|
||||
* @param detector The detector reporting the event - use this to
|
||||
* retrieve extended info about event state.
|
||||
*/
|
||||
public void onScaleEnd(IBCScaleGestureDetector detector);
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* MODIFIED FOR ANTLERSOFT
|
||||
*
|
||||
* Changes for antlersoft/ vnc viewer for android
|
||||
*
|
||||
* Copyright (C) 2010 Michael A. MacDonald
|
||||
*
|
||||
* This 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 software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.FloatMath;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
/**
|
||||
* Detects transformation gestures involving more than one pointer ("multitouch")
|
||||
* using the supplied {@link MotionEvent}s. The {@link OnScaleGestureListener}
|
||||
* callback will notify users when a particular gesture event has occurred.
|
||||
* This class should only be used with {@link MotionEvent}s reported via touch.
|
||||
*
|
||||
* To use this class:
|
||||
* <ul>
|
||||
* <li>Create an instance of the {@code ScaleGestureDetector} for your
|
||||
* {@link View}
|
||||
* <li>In the {@link View#onTouchEvent(MotionEvent)} method ensure you call
|
||||
* {@link #onTouchEvent(MotionEvent)}. The methods defined in your
|
||||
* callback will be executed when the events occur.
|
||||
* </ul>
|
||||
*/
|
||||
class ScaleGestureDetector implements IBCScaleGestureDetector {
|
||||
/**
|
||||
* This value is the threshold ratio between our previous combined pressure
|
||||
* and the current combined pressure. We will only fire an onScale event if
|
||||
* the computed ratio between the current and previous event pressures is
|
||||
* greater than this value. When pressure decreases rapidly between events
|
||||
* the position values can often be imprecise, as it usually indicates
|
||||
* that the user is in the process of lifting a pointer off of the device.
|
||||
* Its value was tuned experimentally.
|
||||
*/
|
||||
private static final float PRESSURE_THRESHOLD = 0.67f;
|
||||
|
||||
private final Context mContext;
|
||||
private final OnScaleGestureListener mListener;
|
||||
private boolean mGestureInProgress;
|
||||
|
||||
private MotionEvent mPrevEvent;
|
||||
private MotionEvent mCurrEvent;
|
||||
|
||||
private float mFocusX;
|
||||
private float mFocusY;
|
||||
private float mPrevFingerDiffX;
|
||||
private float mPrevFingerDiffY;
|
||||
private float mCurrFingerDiffX;
|
||||
private float mCurrFingerDiffY;
|
||||
private float mCurrLen;
|
||||
private float mPrevLen;
|
||||
private float mScaleFactor;
|
||||
private float mCurrPressure;
|
||||
private float mPrevPressure;
|
||||
private long mTimeDelta;
|
||||
|
||||
private final float mEdgeSlop;
|
||||
private float mRightSlopEdge;
|
||||
private float mBottomSlopEdge;
|
||||
private boolean mSloppyGesture;
|
||||
|
||||
public ScaleGestureDetector(Context context, OnScaleGestureListener listener) {
|
||||
ViewConfiguration config = ViewConfiguration.get(context);
|
||||
mContext = context;
|
||||
mListener = listener;
|
||||
mEdgeSlop = config.getScaledEdgeSlop();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#onTouchEvent(android.view.MotionEvent)
|
||||
*/
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
final int action = event.getAction();
|
||||
boolean handled = true;
|
||||
|
||||
if (!mGestureInProgress) {
|
||||
switch (action & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
// We have a new multi-finger gesture
|
||||
|
||||
// as orientation can change, query the metrics in touch down
|
||||
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
|
||||
mRightSlopEdge = metrics.widthPixels - mEdgeSlop;
|
||||
mBottomSlopEdge = metrics.heightPixels - mEdgeSlop;
|
||||
|
||||
// Be paranoid in case we missed an event
|
||||
reset();
|
||||
|
||||
mPrevEvent = MotionEvent.obtain(event);
|
||||
mTimeDelta = 0;
|
||||
|
||||
setContext(event);
|
||||
|
||||
// Check if we have a sloppy gesture. If so, delay
|
||||
// the beginning of the gesture until we're sure that's
|
||||
// what the user wanted. Sloppy gestures can happen if the
|
||||
// edge of the user's hand is touching the screen, for example.
|
||||
final float edgeSlop = mEdgeSlop;
|
||||
final float rightSlop = mRightSlopEdge;
|
||||
final float bottomSlop = mBottomSlopEdge;
|
||||
final float x0 = event.getRawX();
|
||||
final float y0 = event.getRawY();
|
||||
final float x1 = getRawX(event, 1);
|
||||
final float y1 = getRawY(event, 1);
|
||||
|
||||
boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop
|
||||
|| x0 > rightSlop || y0 > bottomSlop;
|
||||
boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop
|
||||
|| x1 > rightSlop || y1 > bottomSlop;
|
||||
|
||||
if (p0sloppy && p1sloppy) {
|
||||
mFocusX = -1;
|
||||
mFocusY = -1;
|
||||
mSloppyGesture = true;
|
||||
} else if (p0sloppy) {
|
||||
mFocusX = event.getX(1);
|
||||
mFocusY = event.getY(1);
|
||||
mSloppyGesture = true;
|
||||
} else if (p1sloppy) {
|
||||
mFocusX = event.getX(0);
|
||||
mFocusY = event.getY(0);
|
||||
mSloppyGesture = true;
|
||||
} else {
|
||||
mGestureInProgress = mListener.onScaleBegin(this);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (mSloppyGesture) {
|
||||
// Initiate sloppy gestures if we've moved outside of the slop area.
|
||||
final float edgeSlop = mEdgeSlop;
|
||||
final float rightSlop = mRightSlopEdge;
|
||||
final float bottomSlop = mBottomSlopEdge;
|
||||
final float x0 = event.getRawX();
|
||||
final float y0 = event.getRawY();
|
||||
final float x1 = getRawX(event, 1);
|
||||
final float y1 = getRawY(event, 1);
|
||||
|
||||
boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop
|
||||
|| x0 > rightSlop || y0 > bottomSlop;
|
||||
boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop
|
||||
|| x1 > rightSlop || y1 > bottomSlop;
|
||||
|
||||
if(p0sloppy && p1sloppy) {
|
||||
mFocusX = -1;
|
||||
mFocusY = -1;
|
||||
} else if (p0sloppy) {
|
||||
mFocusX = event.getX(1);
|
||||
mFocusY = event.getY(1);
|
||||
} else if (p1sloppy) {
|
||||
mFocusX = event.getX(0);
|
||||
mFocusY = event.getY(0);
|
||||
} else {
|
||||
mSloppyGesture = false;
|
||||
mGestureInProgress = mListener.onScaleBegin(this);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
if (mSloppyGesture) {
|
||||
// Set focus point to the remaining finger
|
||||
int id = (((action & MotionEvent.ACTION_POINTER_ID_MASK)
|
||||
>> MotionEvent.ACTION_POINTER_ID_SHIFT) == 0) ? 1 : 0;
|
||||
mFocusX = event.getX(id);
|
||||
mFocusY = event.getY(id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Transform gesture in progress - attempt to handle it
|
||||
switch (action & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
// Gesture ended
|
||||
setContext(event);
|
||||
|
||||
// Set focus point to the remaining finger
|
||||
int id = (((action & MotionEvent.ACTION_POINTER_ID_MASK)
|
||||
>> MotionEvent.ACTION_POINTER_ID_SHIFT) == 0) ? 1 : 0;
|
||||
mFocusX = event.getX(id);
|
||||
mFocusY = event.getY(id);
|
||||
|
||||
if (!mSloppyGesture) {
|
||||
mListener.onScaleEnd(this);
|
||||
}
|
||||
|
||||
reset();
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (!mSloppyGesture) {
|
||||
mListener.onScaleEnd(this);
|
||||
}
|
||||
|
||||
reset();
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
setContext(event);
|
||||
|
||||
// Only accept the event if our relative pressure is within
|
||||
// a certain limit - this can help filter shaky data as a
|
||||
// finger is lifted.
|
||||
if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) {
|
||||
final boolean updatePrevious = mListener.onScale(this);
|
||||
|
||||
if (updatePrevious) {
|
||||
mPrevEvent.recycle();
|
||||
mPrevEvent = MotionEvent.obtain(event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* MotionEvent has no getRawX(int) method; simulate it pending future API approval.
|
||||
*/
|
||||
private static float getRawX(MotionEvent event, int pointerIndex) {
|
||||
float offset = event.getX() - event.getRawX();
|
||||
return event.getX(pointerIndex) + offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* MotionEvent has no getRawY(int) method; simulate it pending future API approval.
|
||||
*/
|
||||
private static float getRawY(MotionEvent event, int pointerIndex) {
|
||||
float offset = event.getY() - event.getRawY();
|
||||
return event.getY(pointerIndex) + offset;
|
||||
}
|
||||
|
||||
private void setContext(MotionEvent curr) {
|
||||
if (mCurrEvent != null) {
|
||||
mCurrEvent.recycle();
|
||||
}
|
||||
mCurrEvent = MotionEvent.obtain(curr);
|
||||
|
||||
mCurrLen = -1;
|
||||
mPrevLen = -1;
|
||||
mScaleFactor = -1;
|
||||
|
||||
final MotionEvent prev = mPrevEvent;
|
||||
|
||||
final float px0 = prev.getX(0);
|
||||
final float py0 = prev.getY(0);
|
||||
final float px1 = prev.getX(1);
|
||||
final float py1 = prev.getY(1);
|
||||
final float cx0 = curr.getX(0);
|
||||
final float cy0 = curr.getY(0);
|
||||
final float cx1 = curr.getX(1);
|
||||
final float cy1 = curr.getY(1);
|
||||
|
||||
final float pvx = px1 - px0;
|
||||
final float pvy = py1 - py0;
|
||||
final float cvx = cx1 - cx0;
|
||||
final float cvy = cy1 - cy0;
|
||||
mPrevFingerDiffX = pvx;
|
||||
mPrevFingerDiffY = pvy;
|
||||
mCurrFingerDiffX = cvx;
|
||||
mCurrFingerDiffY = cvy;
|
||||
|
||||
mFocusX = cx0 + cvx * 0.5f;
|
||||
mFocusY = cy0 + cvy * 0.5f;
|
||||
mTimeDelta = curr.getEventTime() - prev.getEventTime();
|
||||
mCurrPressure = curr.getPressure(0) + curr.getPressure(1);
|
||||
mPrevPressure = prev.getPressure(0) + prev.getPressure(1);
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
if (mPrevEvent != null) {
|
||||
mPrevEvent.recycle();
|
||||
mPrevEvent = null;
|
||||
}
|
||||
if (mCurrEvent != null) {
|
||||
mCurrEvent.recycle();
|
||||
mCurrEvent = null;
|
||||
}
|
||||
mSloppyGesture = false;
|
||||
mGestureInProgress = false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#isInProgress()
|
||||
*/
|
||||
public boolean isInProgress() {
|
||||
return mGestureInProgress;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getFocusX()
|
||||
*/
|
||||
public float getFocusX() {
|
||||
return mFocusX;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getFocusY()
|
||||
*/
|
||||
public float getFocusY() {
|
||||
return mFocusY;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getCurrentSpan()
|
||||
*/
|
||||
public float getCurrentSpan() {
|
||||
if (mCurrLen == -1) {
|
||||
final float cvx = mCurrFingerDiffX;
|
||||
final float cvy = mCurrFingerDiffY;
|
||||
mCurrLen = FloatMath.sqrt(cvx*cvx + cvy*cvy);
|
||||
}
|
||||
return mCurrLen;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getPreviousSpan()
|
||||
*/
|
||||
public float getPreviousSpan() {
|
||||
if (mPrevLen == -1) {
|
||||
final float pvx = mPrevFingerDiffX;
|
||||
final float pvy = mPrevFingerDiffY;
|
||||
mPrevLen = FloatMath.sqrt(pvx*pvx + pvy*pvy);
|
||||
}
|
||||
return mPrevLen;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getScaleFactor()
|
||||
*/
|
||||
public float getScaleFactor() {
|
||||
if (mScaleFactor == -1) {
|
||||
mScaleFactor = getCurrentSpan() / getPreviousSpan();
|
||||
}
|
||||
return mScaleFactor;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getTimeDelta()
|
||||
*/
|
||||
public long getTimeDelta() {
|
||||
return mTimeDelta;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.android.bc.IBCScaleGestureDetector#getEventTime()
|
||||
*/
|
||||
public long getEventTime() {
|
||||
return mCurrEvent.getEventTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* MODIFIED FOR ANTLERSOFT
|
||||
*
|
||||
* Changes for antlersoft/ vnc viewer for android
|
||||
*
|
||||
* Copyright (C) 2010 Michael A. MacDonald
|
||||
*
|
||||
* This 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 software 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 software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
package com.antlersoft.android.bc;
|
||||
|
||||
/**
|
||||
* A convenience class to extend when you only want to listen for a subset
|
||||
* of scaling-related events. This implements all methods in
|
||||
* {@link OnScaleGestureListener} but does nothing.
|
||||
* {@link OnScaleGestureListener#onScale(ScaleGestureDetector)} returns
|
||||
* {@code false} so that a subclass can retrieve the accumulated scale
|
||||
* factor in an overridden onScaleEnd.
|
||||
* {@link OnScaleGestureListener#onScaleBegin(ScaleGestureDetector)} returns
|
||||
* {@code true}.
|
||||
*/
|
||||
public class SimpleOnScaleGestureListener implements OnScaleGestureListener {
|
||||
|
||||
public boolean onScale(IBCScaleGestureDetector detector) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean onScaleBegin(IBCScaleGestureDetector detector) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onScaleEnd(IBCScaleGestureDetector detector) {
|
||||
// Intentionally empty
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package com.antlersoft.android.drawing;
|
||||
|
||||
import com.antlersoft.util.ObjectPool;
|
||||
import com.antlersoft.util.SafeObjectPool;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
|
||||
public class OverlappingCopy
|
||||
{
|
||||
private static SafeObjectPool<Rect> ocRectPool = new SafeObjectPool<Rect>() {
|
||||
@Override
|
||||
protected Rect itemForPool()
|
||||
{
|
||||
return new Rect();
|
||||
}
|
||||
};
|
||||
private static void transformRect(Rect source, Rect transformedSource, int deltaX, int deltaY)
|
||||
{
|
||||
transformedSource.set(deltaX < 0 ? source.right * -1 : source.left,
|
||||
deltaY < 0 ? source.bottom * -1 : source.top,
|
||||
deltaX < 0 ? source.left * -1 : source.right,
|
||||
deltaY < 0 ? source.top * -1 : source.bottom);
|
||||
}
|
||||
private static void copyTransformedRect(Rect stepSourceRect, Rect stepDestRect, int deltaX, int deltaY, Bitmap data, Canvas bitmapBackedCanvas, Paint paint)
|
||||
{
|
||||
transformRect(stepSourceRect,stepSourceRect,deltaX,deltaY);
|
||||
stepDestRect.set(stepSourceRect);
|
||||
stepDestRect.offset(deltaX,deltaY);
|
||||
bitmapBackedCanvas.drawBitmap(data, stepSourceRect, stepDestRect, paint);
|
||||
}
|
||||
public static void Copy(Bitmap data, Canvas bitmapBackedCanvas, Paint paint, Rect source, int destX, int destY)
|
||||
{
|
||||
Copy(data,bitmapBackedCanvas,paint,source,destX,destY,ocRectPool);
|
||||
}
|
||||
public static void Copy(Bitmap data, Canvas bitmapBackedCanvas, Paint paint, Rect source, int destX, int destY, ObjectPool<Rect> rectPool)
|
||||
{
|
||||
//android.util.Log.i("LBM","Copy "+source.toString()+" to "+destX+","+destY);
|
||||
int deltaX = destX - source.left;
|
||||
int deltaY = destY - source.top;
|
||||
int absDeltaX = deltaX < 0 ? -deltaX : deltaX;
|
||||
int absDeltaY = deltaY < 0 ? -deltaY : deltaY;
|
||||
|
||||
// Look for degenerate case
|
||||
if (absDeltaX == 0 && absDeltaY == 0)
|
||||
return;
|
||||
// Look for non-overlap case
|
||||
if (absDeltaX >= source.right - source.left || absDeltaY >= source.bottom - source.top)
|
||||
{
|
||||
// Non-overlapping copy
|
||||
ObjectPool.Entry<Rect> entry = rectPool.reserve();
|
||||
Rect dest = entry.get();
|
||||
dest.set(source.left + deltaX, source.top + deltaY, source.right + deltaX, source.bottom + deltaY);
|
||||
bitmapBackedCanvas.drawBitmap(data, source, dest, paint);
|
||||
rectPool.release(entry);
|
||||
return;
|
||||
}
|
||||
// Determine coordinate transform so that dest rectangle is always down and to the right.
|
||||
ObjectPool.Entry<Rect> transformedSourceEntry = rectPool.reserve();
|
||||
Rect transformedSource = transformedSourceEntry.get();
|
||||
transformRect(source,transformedSource,deltaX,deltaY);
|
||||
ObjectPool.Entry<Rect> transformedDestEntry = rectPool.reserve();
|
||||
Rect transformedDest = transformedDestEntry.get();
|
||||
transformedDest.set(transformedSource);
|
||||
transformedDest.offset(absDeltaX, absDeltaY);
|
||||
ObjectPool.Entry<Rect> intersectEntry = rectPool.reserve();
|
||||
Rect intersect = intersectEntry.get();
|
||||
intersect.setIntersect(transformedSource, transformedDest);
|
||||
|
||||
boolean xStepDone = false;
|
||||
int xStepWidth;
|
||||
int yStepHeight;
|
||||
if (absDeltaX > absDeltaY)
|
||||
{
|
||||
xStepWidth = absDeltaX;
|
||||
yStepHeight = source.bottom - source.top - absDeltaY;
|
||||
}
|
||||
else
|
||||
{
|
||||
xStepWidth = source.right - source.left - absDeltaX;
|
||||
yStepHeight = absDeltaY;
|
||||
}
|
||||
|
||||
ObjectPool.Entry<Rect> stepSourceEntry = rectPool.reserve();
|
||||
Rect stepSourceRect = stepSourceEntry.get();
|
||||
ObjectPool.Entry<Rect> stepDestEntry = rectPool.reserve();
|
||||
Rect stepDestRect = stepDestEntry.get();
|
||||
|
||||
for (int xStep = 0; ! xStepDone; xStep++)
|
||||
{
|
||||
int stepRight = intersect.right - xStep * xStepWidth;
|
||||
int stepLeft = stepRight - xStepWidth;
|
||||
if (stepLeft <= intersect.left)
|
||||
{
|
||||
stepLeft = intersect.left;
|
||||
xStepDone = true;
|
||||
}
|
||||
boolean yStepDone = false;
|
||||
for (int yStep = 0; ! yStepDone; yStep++)
|
||||
{
|
||||
int stepBottom = intersect.bottom - yStep * yStepHeight;
|
||||
int stepTop = stepBottom - yStepHeight;
|
||||
if (stepTop <= intersect.top)
|
||||
{
|
||||
stepTop = intersect.top;
|
||||
yStepDone = true;
|
||||
}
|
||||
stepSourceRect.set(stepLeft,stepTop,stepRight,stepBottom);
|
||||
//android.util.Log.i("LBM","Copy transformed "+stepSourceRect.toString()+" "+deltaX+" "+deltaY);
|
||||
copyTransformedRect(stepSourceRect, stepDestRect, deltaX, deltaY, data, bitmapBackedCanvas, paint);
|
||||
}
|
||||
}
|
||||
if (absDeltaX>0)
|
||||
{
|
||||
// Copy left edge
|
||||
stepSourceRect.set(transformedSource.left,transformedSource.top,intersect.left,transformedSource.bottom);
|
||||
copyTransformedRect(stepSourceRect, stepDestRect, deltaX, deltaY, data, bitmapBackedCanvas, paint);
|
||||
}
|
||||
if (absDeltaY>0)
|
||||
{
|
||||
// Copy top excluding left edge
|
||||
stepSourceRect.set(intersect.left,transformedSource.top,transformedSource.right,intersect.top);
|
||||
copyTransformedRect(stepSourceRect, stepDestRect, deltaX, deltaY, data, bitmapBackedCanvas, paint);
|
||||
}
|
||||
|
||||
rectPool.release(stepDestEntry);
|
||||
rectPool.release(stepSourceEntry);
|
||||
rectPool.release(intersectEntry);
|
||||
rectPool.release(transformedDestEntry);
|
||||
rectPool.release(transformedSourceEntry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
549
app/src/main/java/com/antlersoft/android/drawing/RectList.java
Normal file
@@ -0,0 +1,549 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.android.drawing;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.antlersoft.util.ObjectPool;
|
||||
|
||||
/**
|
||||
* A list of rectangular regions that together represent an area of interest. Provides
|
||||
* a set of operations that apply to the whole area, adding, changing and mutating the
|
||||
* rectangles in the list as required.
|
||||
* <p>
|
||||
* Invariants: None of the rectangles in the list overlap; no pair of rectangles in the list
|
||||
* together make a single rectangle (none share a complete side)
|
||||
* </p>
|
||||
* <p>
|
||||
* Instances of this class are not thread safe
|
||||
* </p>
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
public class RectList {
|
||||
|
||||
enum OverlapType {
|
||||
NONE,
|
||||
SAME,
|
||||
CONTAINS,
|
||||
CONTAINED_BY,
|
||||
COALESCIBLE,
|
||||
PARTIAL
|
||||
}
|
||||
|
||||
static final int LEFT = 1;
|
||||
static final int TOP_LEFT = 2;
|
||||
static final int TOP = 4;
|
||||
static final int TOP_RIGHT = 8;
|
||||
static final int RIGHT = 16;
|
||||
static final int BOTTOM_RIGHT = 32;
|
||||
static final int BOTTOM = 64;
|
||||
static final int BOTTOM_LEFT = 128;
|
||||
|
||||
/**
|
||||
* The part left over when one rectangle is subtracted from another
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
static class NonOverlappingPortion
|
||||
{
|
||||
Rect leftPortion;
|
||||
Rect topLeftPortion;
|
||||
Rect topPortion;
|
||||
Rect topRightPortion;
|
||||
Rect rightPortion;
|
||||
Rect bottomRightPortion;
|
||||
Rect bottomPortion;
|
||||
Rect bottomLeftPortion;
|
||||
|
||||
int r1Owns;
|
||||
int r2Owns;
|
||||
int common;
|
||||
int adjacent;
|
||||
boolean horizontalOverlap;
|
||||
boolean verticalOverlap;
|
||||
|
||||
Rect coalesced;
|
||||
|
||||
NonOverlappingPortion()
|
||||
{
|
||||
leftPortion = new Rect();
|
||||
topLeftPortion = new Rect();
|
||||
topPortion = new Rect();
|
||||
topRightPortion = new Rect();
|
||||
rightPortion = new Rect();
|
||||
bottomRightPortion = new Rect();
|
||||
bottomPortion = new Rect();
|
||||
bottomLeftPortion = new Rect();
|
||||
coalesced = new Rect();
|
||||
}
|
||||
|
||||
void setCornerOwnership(int side1, int side2, int corner)
|
||||
{
|
||||
int combined = (side1 | side2);
|
||||
if ((r1Owns & combined) == combined)
|
||||
r1Owns |= corner;
|
||||
else if ((r2Owns & combined) == combined)
|
||||
r2Owns |= corner;
|
||||
}
|
||||
|
||||
void setCornerOwnership()
|
||||
{
|
||||
setCornerOwnership(LEFT,TOP,TOP_LEFT);
|
||||
setCornerOwnership(TOP,RIGHT,TOP_RIGHT);
|
||||
setCornerOwnership(BOTTOM,RIGHT,BOTTOM_RIGHT);
|
||||
setCornerOwnership(BOTTOM,LEFT,BOTTOM_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates with the borders remaining when r2 is subtracted from r1
|
||||
* @param r1
|
||||
* @param r2
|
||||
* @return
|
||||
*/
|
||||
OverlapType overlap(Rect r1, Rect r2)
|
||||
{
|
||||
r1Owns = 0;
|
||||
r2Owns = 0;
|
||||
common = 0;
|
||||
adjacent = 0;
|
||||
OverlapType result = OverlapType.NONE;
|
||||
horizontalOverlap = false;
|
||||
verticalOverlap = false;
|
||||
|
||||
if (r1.left < r2.left)
|
||||
{
|
||||
leftPortion.left = topLeftPortion.left = bottomLeftPortion.left = r1.left;
|
||||
if (r2.left < r1.right) {
|
||||
leftPortion.right = topLeftPortion.right = bottomLeftPortion.right = topPortion.left = bottomPortion.left = r2.left;
|
||||
horizontalOverlap = true;
|
||||
} else {
|
||||
leftPortion.right = topLeftPortion.right = bottomLeftPortion.right = topPortion.left = bottomPortion.left = r1.right;
|
||||
if (r2.left == r1.right)
|
||||
adjacent |= LEFT;
|
||||
}
|
||||
r1Owns |= LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
leftPortion.left = topLeftPortion.left = bottomLeftPortion.left = r2.left;
|
||||
if (r1.left < r2.right) {
|
||||
leftPortion.right = topLeftPortion.right = bottomLeftPortion.right = topPortion.left = bottomPortion.left = r1.left;
|
||||
horizontalOverlap = true;
|
||||
} else {
|
||||
leftPortion.right = topLeftPortion.right = bottomLeftPortion.right = topPortion.left = bottomPortion.left = r2.right;
|
||||
if ( r1.left == r2.right)
|
||||
adjacent |= RIGHT;
|
||||
}
|
||||
if (r2.left < r1.left)
|
||||
r2Owns |= LEFT;
|
||||
else
|
||||
common |= LEFT;
|
||||
}
|
||||
if (r1.top < r2.top)
|
||||
{
|
||||
topPortion.top = topLeftPortion.top = topRightPortion.top = r1.top;
|
||||
if (r2.top < r1.bottom) {
|
||||
topPortion.bottom = topLeftPortion.bottom = topRightPortion.bottom = leftPortion.top = rightPortion.top = r2.top;
|
||||
verticalOverlap = true;
|
||||
} else {
|
||||
topPortion.bottom = topLeftPortion.bottom = topRightPortion.bottom = leftPortion.top = rightPortion.top = r1.bottom;
|
||||
if (r2.top == r1.bottom)
|
||||
adjacent |= TOP;
|
||||
}
|
||||
r1Owns |= TOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
topPortion.top = topLeftPortion.top = topRightPortion.top = r2.top;
|
||||
if (r1.top < r2.bottom) {
|
||||
topPortion.bottom = topLeftPortion.bottom = topRightPortion.bottom = leftPortion.top = rightPortion.top = r1.top;
|
||||
verticalOverlap = true;
|
||||
} else {
|
||||
topPortion.bottom = topLeftPortion.bottom = topRightPortion.bottom = leftPortion.top = rightPortion.top = r2.bottom;
|
||||
if (r1.top == r2.bottom)
|
||||
adjacent |= BOTTOM;
|
||||
}
|
||||
if (r2.top < r1.top)
|
||||
r2Owns |= TOP;
|
||||
else
|
||||
common |= TOP;
|
||||
}
|
||||
if (r1.right > r2.right)
|
||||
{
|
||||
rightPortion.right = topRightPortion.right = bottomRightPortion.right = r1.right;
|
||||
if (r2.right > r1.left) {
|
||||
rightPortion.left = topRightPortion.left = bottomRightPortion.left = topPortion.right = bottomPortion.right = r2.right;
|
||||
horizontalOverlap = true;
|
||||
} else {
|
||||
rightPortion.left = topRightPortion.left = bottomRightPortion.left = topPortion.right = bottomPortion.right = r1.left;
|
||||
if (r2.right == r1.left)
|
||||
adjacent |= RIGHT;
|
||||
}
|
||||
r1Owns |= RIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
rightPortion.right = topRightPortion.right = bottomRightPortion.right = r2.right;
|
||||
if (r1.right > r2.left) {
|
||||
rightPortion.left = topRightPortion.left = bottomRightPortion.left = topPortion.right = bottomPortion.right = r1.right;
|
||||
horizontalOverlap = true;
|
||||
} else {
|
||||
rightPortion.left = topRightPortion.left = bottomRightPortion.left = topPortion.right = bottomPortion.right = r2.left;
|
||||
if (r1.right==r2.left)
|
||||
adjacent |= LEFT;
|
||||
}
|
||||
if (r2.right > r1.right)
|
||||
r2Owns |= RIGHT;
|
||||
else
|
||||
common |= RIGHT;
|
||||
}
|
||||
if (r1.bottom > r2.bottom)
|
||||
{
|
||||
bottomPortion.bottom = bottomLeftPortion.bottom = bottomRightPortion.bottom = r1.bottom;
|
||||
if (r2.bottom > r1.top) {
|
||||
bottomPortion.top = bottomLeftPortion.top = bottomRightPortion.top = leftPortion.bottom = rightPortion.bottom = r2.bottom;
|
||||
verticalOverlap = true;
|
||||
} else {
|
||||
bottomPortion.top = bottomLeftPortion.top = bottomRightPortion.top = leftPortion.bottom = rightPortion.bottom = r1.top;
|
||||
if (r2.bottom==r1.top)
|
||||
adjacent |= BOTTOM;
|
||||
}
|
||||
r1Owns |= BOTTOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
bottomPortion.bottom = bottomLeftPortion.bottom = bottomRightPortion.bottom = r2.bottom;
|
||||
if (r1.bottom > r2.top) {
|
||||
bottomPortion.top = bottomLeftPortion.top = bottomRightPortion.top = leftPortion.bottom = rightPortion.bottom = r1.bottom;
|
||||
verticalOverlap = true;
|
||||
} else {
|
||||
bottomPortion.top = bottomLeftPortion.top = bottomRightPortion.top = leftPortion.bottom = rightPortion.bottom = r2.top;
|
||||
if (r1.bottom==r2.top)
|
||||
adjacent |= TOP;
|
||||
}
|
||||
if (r2.bottom > r1.bottom)
|
||||
r2Owns |= BOTTOM;
|
||||
else
|
||||
common |= BOTTOM;
|
||||
}
|
||||
if ( common == (LEFT|RIGHT|TOP|BOTTOM))
|
||||
{
|
||||
result = OverlapType.SAME;
|
||||
}
|
||||
else if ((common & (LEFT|RIGHT)) == (LEFT | RIGHT) && (verticalOverlap || (adjacent & (TOP | BOTTOM)) != 0))
|
||||
{
|
||||
result = OverlapType.COALESCIBLE;
|
||||
coalesced.left = r1.left;
|
||||
coalesced.right = r1.right;
|
||||
coalesced.top = topPortion.top;
|
||||
coalesced.bottom = bottomPortion.bottom;
|
||||
}
|
||||
else if ((common & (TOP | BOTTOM)) == (TOP | BOTTOM) && (horizontalOverlap || (adjacent & (LEFT | RIGHT)) != 0))
|
||||
{
|
||||
result = OverlapType.COALESCIBLE;
|
||||
coalesced.left = leftPortion.left;
|
||||
coalesced.right = rightPortion.right;
|
||||
coalesced.top = r1.top;
|
||||
coalesced.bottom = r1.bottom;
|
||||
}
|
||||
else if (verticalOverlap && horizontalOverlap) {
|
||||
if (r2Owns == 0)
|
||||
{
|
||||
result = OverlapType.CONTAINED_BY;
|
||||
}
|
||||
else if (r1Owns == 0)
|
||||
{
|
||||
result = OverlapType.CONTAINS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Partial overlap, non coalescible case
|
||||
result = OverlapType.PARTIAL;
|
||||
setCornerOwnership();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Up to 8 Rect objects
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
static class NonOverlappingRects
|
||||
{
|
||||
ObjectPool.Entry<Rect>[] rectEntries;
|
||||
int count;
|
||||
static final int MAX_RECTS = 8;
|
||||
|
||||
NonOverlappingRects()
|
||||
{
|
||||
rectEntries = new ObjectPool.Entry[MAX_RECTS];
|
||||
}
|
||||
|
||||
private void addOwnedRect(int owner, int direction, ObjectPool<Rect> pool, Rect r)
|
||||
{
|
||||
if ((owner & direction)==direction)
|
||||
{
|
||||
ObjectPool.Entry<Rect> entry = pool.reserve();
|
||||
rectEntries[count++] = entry;
|
||||
entry.get().set(r);
|
||||
}
|
||||
}
|
||||
|
||||
void Populate(NonOverlappingPortion p, ObjectPool<Rect> pool, int owner)
|
||||
{
|
||||
count = 0;
|
||||
for (int i=0; i<MAX_RECTS; i++)
|
||||
rectEntries[i] = null;
|
||||
addOwnedRect(owner,BOTTOM_LEFT,pool,p.bottomLeftPortion);
|
||||
addOwnedRect(owner,BOTTOM,pool,p.bottomPortion);
|
||||
addOwnedRect(owner,BOTTOM_RIGHT,pool,p.bottomRightPortion);
|
||||
addOwnedRect(owner,BOTTOM,pool,p.bottomPortion);
|
||||
addOwnedRect(owner,TOP_RIGHT,pool,p.topRightPortion);
|
||||
addOwnedRect(owner,TOP,pool,p.topPortion);
|
||||
addOwnedRect(owner,TOP_LEFT,pool,p.topLeftPortion);
|
||||
addOwnedRect(owner,LEFT,pool,p.leftPortion);
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<ObjectPool.Entry<Rect>> list;
|
||||
private ObjectPool<Rect> pool;
|
||||
private ObjectPool<NonOverlappingRects> nonOverlappingRectsPool = new ObjectPool<NonOverlappingRects>() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.util.ObjectPool#itemForPool()
|
||||
*/
|
||||
@Override
|
||||
protected NonOverlappingRects itemForPool() {
|
||||
return new NonOverlappingRects();
|
||||
}
|
||||
|
||||
};
|
||||
private ObjectPool<ArrayList<ObjectPool.Entry<Rect>>> listRectsPool = new ObjectPool<ArrayList<ObjectPool.Entry<Rect>>>() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.util.ObjectPool#itemForPool()
|
||||
*/
|
||||
@Override
|
||||
protected ArrayList<Entry<Rect>> itemForPool() {
|
||||
return new ArrayList<Entry<Rect>>(NonOverlappingRects.MAX_RECTS);
|
||||
}
|
||||
};
|
||||
private NonOverlappingPortion nonOverlappingPortion;
|
||||
|
||||
public RectList(ObjectPool<Rect> pool)
|
||||
{
|
||||
this.pool = pool;
|
||||
list = new ArrayList<ObjectPool.Entry<Rect>>();
|
||||
nonOverlappingPortion = new NonOverlappingPortion();
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return list.size();
|
||||
}
|
||||
|
||||
public Rect get(int i)
|
||||
{
|
||||
return list.get(i).get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all rectangles from the list and release them from the pool
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
for (int i=list.size()-1; i>=0; i--)
|
||||
{
|
||||
ObjectPool.Entry<Rect> r = list.get(i);
|
||||
pool.release(r);
|
||||
}
|
||||
list.clear();
|
||||
}
|
||||
|
||||
private void recursiveAdd(ObjectPool.Entry<Rect> toAdd, int level)
|
||||
{
|
||||
if (level>=list.size())
|
||||
{
|
||||
list.add(toAdd);
|
||||
return;
|
||||
}
|
||||
Rect addRect = toAdd.get();
|
||||
ObjectPool.Entry<Rect> thisEntry = list.get(level);
|
||||
Rect thisRect = thisEntry.get();
|
||||
switch (nonOverlappingPortion.overlap(thisRect, addRect))
|
||||
{
|
||||
case NONE :
|
||||
recursiveAdd(toAdd,level + 1);
|
||||
break;
|
||||
case SAME :
|
||||
case CONTAINS :
|
||||
pool.release(toAdd);
|
||||
break;
|
||||
case CONTAINED_BY :
|
||||
pool.release(thisEntry);
|
||||
list.remove(level);
|
||||
recursiveAdd(toAdd,level);
|
||||
break;
|
||||
case COALESCIBLE :
|
||||
pool.release(thisEntry);
|
||||
list.remove(level);
|
||||
addRect.set(nonOverlappingPortion.coalesced);
|
||||
recursiveAdd(toAdd,0);
|
||||
break;
|
||||
case PARTIAL :
|
||||
pool.release(toAdd);
|
||||
ObjectPool.Entry<NonOverlappingRects> rectsEntry = nonOverlappingRectsPool.reserve();
|
||||
NonOverlappingRects rects = rectsEntry.get();
|
||||
rects.Populate(nonOverlappingPortion,pool,nonOverlappingPortion.r2Owns);
|
||||
for (int i=0; i<rects.count; i++)
|
||||
{
|
||||
recursiveAdd(rects.rectEntries[i],0);
|
||||
}
|
||||
nonOverlappingRectsPool.release(rectsEntry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a rectangle to the region of interest
|
||||
* @param toAdd
|
||||
*/
|
||||
public void add(Rect toAdd)
|
||||
{
|
||||
// Create a copy of the rect to work with
|
||||
ObjectPool.Entry<Rect> entry = pool.reserve();
|
||||
Rect r = entry.get();
|
||||
r.set(toAdd);
|
||||
recursiveAdd(entry,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the rectangle of interest to include only those portions
|
||||
* that fall inside bounds.
|
||||
* @param bounds
|
||||
*/
|
||||
public void intersect(Rect bounds)
|
||||
{
|
||||
int size = list.size();
|
||||
ObjectPool.Entry<ArrayList<ObjectPool.Entry<Rect>>> listEntry = listRectsPool.reserve();
|
||||
ArrayList<ObjectPool.Entry<Rect>> newList = listEntry.get();
|
||||
newList.clear();
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
ObjectPool.Entry<Rect> entry = list.get(i);
|
||||
Rect rect = entry.get();
|
||||
if (rect.intersect(bounds))
|
||||
{
|
||||
newList.add(entry);
|
||||
}
|
||||
else
|
||||
pool.release(entry);
|
||||
}
|
||||
list.clear();
|
||||
size = newList.size();
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
recursiveAdd(newList.get(i),0);
|
||||
}
|
||||
listRectsPool.release(listEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a rectangle intersects any part of the area of interest
|
||||
* @param r
|
||||
* @return True if r intersects any rectangle in the list
|
||||
*/
|
||||
public boolean testIntersect(Rect r)
|
||||
{
|
||||
int l = list.size();
|
||||
|
||||
for (int i = 0; i<l; i++)
|
||||
{
|
||||
if (list.get(i).get().intersects(r.left, r.top, r.right, r.bottom))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the rectangle from the area of interest.
|
||||
* @param toSubtract
|
||||
*/
|
||||
public void subtract(Rect toSubtract)
|
||||
{
|
||||
int size = list.size();
|
||||
ObjectPool.Entry<ArrayList<ObjectPool.Entry<Rect>>> listEntry = listRectsPool.reserve();
|
||||
ArrayList<ObjectPool.Entry<Rect>> newList = listEntry.get();
|
||||
newList.clear();
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
ObjectPool.Entry<Rect> entry = list.get(i);
|
||||
Rect rect = entry.get();
|
||||
switch (nonOverlappingPortion.overlap(rect, toSubtract))
|
||||
{
|
||||
case SAME:
|
||||
pool.release(entry);
|
||||
newList.clear();
|
||||
list.remove(i);
|
||||
return;
|
||||
case CONTAINED_BY:
|
||||
pool.release(entry);
|
||||
list.remove(i);
|
||||
i--;
|
||||
size--;
|
||||
break;
|
||||
case NONE:
|
||||
break;
|
||||
case COALESCIBLE:
|
||||
if (!nonOverlappingPortion.verticalOverlap || ! nonOverlappingPortion.horizontalOverlap)
|
||||
break;
|
||||
case CONTAINS :
|
||||
nonOverlappingPortion.setCornerOwnership();
|
||||
case PARTIAL :
|
||||
{
|
||||
ObjectPool.Entry<NonOverlappingRects> rectsEntry = nonOverlappingRectsPool.reserve();
|
||||
NonOverlappingRects rects = rectsEntry.get();
|
||||
rects.Populate(nonOverlappingPortion, pool, nonOverlappingPortion.r1Owns);
|
||||
pool.release(entry);
|
||||
list.remove(i);
|
||||
i--;
|
||||
size--;
|
||||
for (int j=0; j<rects.count; j++)
|
||||
{
|
||||
newList.add(rects.rectEntries[j]);
|
||||
}
|
||||
nonOverlappingRectsPool.release(rectsEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
size = newList.size();
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
recursiveAdd(newList.get(i),0);
|
||||
}
|
||||
listRectsPool.release(listEntry);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.append("{\n");
|
||||
for (int i=0; i<getSize(); i++)
|
||||
{
|
||||
sb.append(get(i).toString());
|
||||
sb.append("\n");
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
83
app/src/main/java/com/antlersoft/util/ByteBufferStack.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.antlersoft.util;
|
||||
|
||||
/**
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
public class ByteBufferStack {
|
||||
private byte[] m_buffer;
|
||||
private int[] m_offsets;
|
||||
private int m_depth;
|
||||
private int m_max_depth;
|
||||
private int m_max_size;
|
||||
|
||||
public static final int MAX_DEPTH = 20;
|
||||
public static final int MAX_SIZE = 1048;
|
||||
public ByteBufferStack(int maxDepth, int maxSize)
|
||||
{
|
||||
m_depth = 0;
|
||||
m_max_depth = maxDepth;
|
||||
m_max_size = maxSize;
|
||||
m_offsets= new int[maxDepth];
|
||||
m_buffer = new byte[maxSize];
|
||||
}
|
||||
|
||||
public ByteBufferStack()
|
||||
{
|
||||
this(MAX_DEPTH, MAX_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Start of the buffer; this value is valid at least until the next call of reserve()
|
||||
*/
|
||||
public byte[] getBuffer()
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return Offset in getBuffer() of last reserved region
|
||||
*/
|
||||
public int getOffset()
|
||||
{
|
||||
return m_offsets[m_depth];
|
||||
}
|
||||
|
||||
public int reserve(int count)
|
||||
{
|
||||
if (count < 0 || (count + m_max_size < 0))
|
||||
throw new IllegalArgumentException("Count must by greater than 0");
|
||||
if (m_depth == m_max_depth)
|
||||
{
|
||||
m_max_depth *= 2;
|
||||
int[] new_offsets = new int[m_max_depth];
|
||||
System.arraycopy(m_offsets, 0, new_offsets, 0, m_depth);
|
||||
m_offsets = new_offsets;
|
||||
}
|
||||
int result = m_offsets[m_depth];
|
||||
int new_size = result + count;
|
||||
m_offsets[m_depth++] = new_size;
|
||||
if (new_size > m_max_size)
|
||||
{
|
||||
m_max_size = Math.max(2 * m_max_size, new_size);
|
||||
byte[] new_buffer = new byte[m_max_size];
|
||||
System.arraycopy(m_buffer, 0, new_buffer, 0, result);
|
||||
m_buffer = new_buffer;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void release()
|
||||
{
|
||||
if (m_depth<1)
|
||||
{
|
||||
throw new IllegalStateException("release() without reserve()");
|
||||
}
|
||||
m_depth--;
|
||||
}
|
||||
}
|
||||
58
app/src/main/java/com/antlersoft/util/ObjectPool.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.util;
|
||||
|
||||
/**
|
||||
* A pool of reusable object of a given type. You get the object from a Entry, which you get
|
||||
* by calling reserve(). When you are done with the object, you call release() passing the Entry.
|
||||
* <p>
|
||||
* Failing to call release() does not leak memory--but you will not get the benefits
|
||||
* of reusing the object. You will run into contention issues if you
|
||||
* call release() while still holding a reference to the pool object.
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
public abstract class ObjectPool<R> {
|
||||
public static class Entry<S> {
|
||||
S item;
|
||||
Entry<S> nextEntry;
|
||||
|
||||
Entry(S i, Entry<S> n)
|
||||
{
|
||||
item = i;
|
||||
nextEntry = n;
|
||||
}
|
||||
|
||||
public S get() {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
private Entry<R> next;
|
||||
public ObjectPool()
|
||||
{
|
||||
next = null;
|
||||
}
|
||||
|
||||
public Entry<R> reserve()
|
||||
{
|
||||
if (next == null)
|
||||
{
|
||||
next = new Entry<R>(itemForPool(), null);
|
||||
}
|
||||
Entry<R> result = next;
|
||||
next = result.nextEntry;
|
||||
result.nextEntry = null;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void release(Entry<R> entry)
|
||||
{
|
||||
entry.nextEntry = next;
|
||||
next = entry;
|
||||
}
|
||||
|
||||
protected abstract R itemForPool();
|
||||
}
|
||||
29
app/src/main/java/com/antlersoft/util/SafeObjectPool.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (C) 2009 Michael A. MacDonald
|
||||
*/
|
||||
package com.antlersoft.util;
|
||||
|
||||
/**
|
||||
* Synchronized object pool
|
||||
* @author Michael A. MacDonald
|
||||
*
|
||||
*/
|
||||
public abstract class SafeObjectPool<R> extends ObjectPool<R> {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.util.ObjectPool#release(com.antlersoft.util.ObjectPool.Entry)
|
||||
*/
|
||||
@Override
|
||||
public synchronized void release(com.antlersoft.util.ObjectPool.Entry<R> entry) {
|
||||
super.release(entry);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.antlersoft.util.ObjectPool#reserve()
|
||||
*/
|
||||
@Override
|
||||
public synchronized com.antlersoft.util.ObjectPool.Entry<R> reserve() {
|
||||
return super.reserve();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Dummy package
|
||||
*/
|
||||
/**
|
||||
* @author nito
|
||||
*
|
||||
*/
|
||||
package com.theqvd.android.client;
|
||||
352
app/src/main/java/com/theqvd/android/xpro/Config.java
Normal file
@@ -0,0 +1,352 @@
|
||||
/**
|
||||
* Singleton Class to hold all the configuration strings
|
||||
*
|
||||
* Copyright 2009-2014 by Qindel Formacion y Servicios S.L.
|
||||
*
|
||||
* xvncpro 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* xvncpro 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.
|
||||
*
|
||||
*/
|
||||
package com.theqvd.android.xpro;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Point;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.WindowManager;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
/**
|
||||
*
|
||||
* Class to hold all the configuration strings + the persistent configuration
|
||||
* of the application stored in the property files
|
||||
*
|
||||
* @author nito
|
||||
*
|
||||
*/
|
||||
|
||||
public class Config {
|
||||
public final static String specialAndroid22Extension = ".ogg";
|
||||
public final static String assetscopydir = "xserver";
|
||||
public final static String vnccmd = "vnc://localhost:5900/C24bit/ben1to";
|
||||
public final static String x11cmd = "x11://localhost:6000";
|
||||
private static String targetdir;
|
||||
public static String xvnc;
|
||||
public static String xvnccmd;
|
||||
public static String pocketvncconfigfullpath;
|
||||
|
||||
// public final static String xvnc = targetdir + "/usr/X11R6/bin/" + xvncbinary;
|
||||
// public final static String xvnccmd = xvnc + " :0 -br -localhost -nolisten local -PasswordFile="+targetdir+"/etc/vncpasswd";
|
||||
public static String xvncbinary = L.xvncbinary;
|
||||
public final static String notAllowRemoteVncConns = "-localhost";
|
||||
public final static String psxvnccmd = "/system/bin/ps "+L.xvncbinary;
|
||||
public final static String serverstartedstring = "^.*?created VNC server for screen 0";
|
||||
public final static String vncdisconnectedstring = ".*?Connections: closed: 127.0.0.1.*";
|
||||
// Connections: closed: 127.0.0.1::51506
|
||||
// Property strings in the property file
|
||||
public final static String props_hasbeencopied = "hasbeencopied";
|
||||
public final static String props_pocketconfigcopied = "pocketconfigcopied";
|
||||
public final static String props_forcexresolution = "forcexresolution";
|
||||
public final static String props_widthpixels = "widthpixels";
|
||||
public final static String props_heightpixels = "heightpixels";
|
||||
public final static String props_keep_x_running = "keepxrunning";
|
||||
public final static String props_use_android_vnc = "useandroidvnc";
|
||||
public final static String props_remote_vnc = "useremotevnc";
|
||||
public final static String props_render = "userender";
|
||||
public final static String props_xinerama = "usexinerama";
|
||||
public final static String helpurl = "http://docs.theqvd.com/";
|
||||
public final static int minPixels = 32;
|
||||
public final static int maxPixels = 10000;
|
||||
public final static boolean debug = false;
|
||||
public final static int notifycopy = 1;
|
||||
public final static int notifystartx = 2;
|
||||
public final static int notifynovncinstalled = 3;
|
||||
public final static int xvncsizerequired = 40; /* 37 MB required */
|
||||
public final static long xvncsizerequiredinkbytes = xvncsizerequired * 1024L;
|
||||
public final static String pocketvncconfig = "xvnc.vnc";
|
||||
// public static String pocketvncconfigfullpath = targetdir + Config.pocketvncconfig;
|
||||
public final static int INSTALLPACKAGE=1;
|
||||
public final static int SENDALERT=0;
|
||||
public final static int SETCOPYPROGRESS=1;
|
||||
public final static int SETPROGRESSVISIBILITY=2;
|
||||
public final static int UPDATEBUTTONS=3;
|
||||
public final static int PRERREQUISITEINSTALLED=4;
|
||||
public final static int[] messageType = {
|
||||
SENDALERT, // uses messageTitle and messageText in the setData
|
||||
SETCOPYPROGRESS, // uses progress in the setData
|
||||
SETPROGRESSVISIBILITY, // uses progressvisibility in the setData
|
||||
UPDATEBUTTONS, // no parameters
|
||||
PRERREQUISITEINSTALLED, // no parameters
|
||||
};
|
||||
public final static String messageTitle = "title";
|
||||
public final static String messageText = "text";
|
||||
public final static String copyProgress = "progress";
|
||||
public final static String progressVisibility = "progressVisibility";
|
||||
// StartActivityForResult codes
|
||||
public final static int vncActivityRequestCode = 11;
|
||||
|
||||
|
||||
public static String getAbout(String version) {
|
||||
return "XVnc\nLicense: Licensed under the GPLv3.\nAuthor: support@theqvd.com\nSponsored: http://theqvd.com\nVersion: "+version+"\nRevision: $Revision: 26639 $\nDate: $Date: 2015-03-31 11:51:02 +0200 (Tue, 31 Mar 2015) $";
|
||||
}
|
||||
// Class info
|
||||
static final String tag = L.xvncbinary + "-Config-" +java.util.Map.Entry.class.getSimpleName();
|
||||
private static Context context;
|
||||
private static Activity activity;
|
||||
private static boolean appConfig_force_x_geometry = false,
|
||||
appConfig_keep_x_running = false,
|
||||
appConfig_remote_vnc_allowed = false,
|
||||
appConfig_render = true,
|
||||
appConfig_xinerama = false;
|
||||
private static int appConfig_height_pixels = 0, appConfig_width_pixels = 0,
|
||||
appConfig_defaultHeightPixels = 0, appconfig_defaultWidthPixels = 0;
|
||||
private static VncViewerAndroid androidvncviewer;
|
||||
private static Handler uiHandler;
|
||||
// private Prerrequisite[] prerrequisites;
|
||||
// Set installPrerrequisitesOnStart to true if you want to finish the activity
|
||||
// after installation
|
||||
private static boolean installPrerrequisitesOnStart = false;
|
||||
|
||||
private void init() {
|
||||
Log.i(tag, "The CPU type from CPU_ABI is "+android.os.Build.CPU_ABI);
|
||||
setTargetdir(Tools.datapath + "/xvncfiles");
|
||||
pocketvncconfigfullpath = getTargetdir() + "/" + Config.pocketvncconfig;
|
||||
xvnc = getTargetdir() + "/usr/X11R6/bin/" + L.xvncbinary;
|
||||
if (android.os.Build.CPU_ABI.equals("x86")) {
|
||||
xvnc += "i386";
|
||||
} else if (android.os.Build.CPU_ABI.startsWith("arm")) {
|
||||
// do not do anything
|
||||
} else {
|
||||
Log.e(tag, "Unknown CPU_ABI is neither x86 and not arm*");
|
||||
// TODO throw error here?
|
||||
}
|
||||
//xvnc += specialAndroid22Extension;
|
||||
|
||||
|
||||
xvnccmd = xvnc + " :0 -br -nolisten local -pixelformat rgb888 -pixdepths 1 4 8 15 16 24 32 -PasswordFile="+getTargetdir()+"/etc/vncpasswd";
|
||||
setHeightAndWidth();
|
||||
load_properties();
|
||||
}
|
||||
|
||||
public Config(Context c) {
|
||||
context = c;
|
||||
init();
|
||||
}
|
||||
public Config(Activity a) {
|
||||
context = a;
|
||||
activity = a;
|
||||
init();
|
||||
}
|
||||
|
||||
private void setHeightAndWidth() {
|
||||
// Set height and width
|
||||
WindowManager w = activity.getWindowManager();
|
||||
Display d = w.getDefaultDisplay();
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
d.getMetrics(metrics);
|
||||
// since SDK_INT = 1;
|
||||
int widthPixels = metrics.widthPixels;
|
||||
int heightPixels = metrics.heightPixels;
|
||||
Log.d(tag, "setHeightAndWidth:The Build.VERSION is:"+Build.VERSION.SDK_INT+
|
||||
" and the initial width and height is:"+widthPixels+","+heightPixels);
|
||||
|
||||
// includes window decorations (statusbar bar/menu bar)
|
||||
if (Build.VERSION.SDK_INT >= 17)
|
||||
try {
|
||||
Log.d(tag, "setHeightAndWidth:The Build.VERSION is greater than 17:"+Build.VERSION.SDK_INT);
|
||||
Point realSize = new Point();
|
||||
Display.class.getMethod("getSize", Point.class).invoke(d, realSize); //getRealSize gets full screen without decorations
|
||||
// Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
|
||||
widthPixels = realSize.x;
|
||||
heightPixels = realSize.y;
|
||||
Log.d(tag, "setHeightAndWidth:The Build.VERSION is greater than 17:"+Build.VERSION.SDK_INT+
|
||||
" and the width and height is:"+widthPixels+","+heightPixels);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
// force landscape hack
|
||||
appConfig_height_pixels = appConfig_defaultHeightPixels = (heightPixels > widthPixels) ? widthPixels : heightPixels;
|
||||
appConfig_width_pixels = appconfig_defaultWidthPixels = (heightPixels > widthPixels) ? heightPixels : widthPixels;
|
||||
Log.d(tag, "setHeightAndWidth: The final and the end width and height is:"+
|
||||
appconfig_defaultWidthPixels+","+appConfig_defaultHeightPixels);
|
||||
}
|
||||
|
||||
|
||||
private void load_properties() {
|
||||
// Use default settings
|
||||
// appConfig_force_x_geometry = true;
|
||||
// appConfig_keep_x_running = true;
|
||||
|
||||
/*
|
||||
SharedPreferences prefsPrivate;
|
||||
prefsPrivate = context.getSharedPreferences("PREFS_PRIVATE", Context.MODE_PRIVATE);
|
||||
appConfig_force_x_geometry = prefsPrivate.getBoolean(Config.props_forcexresolution, appConfig_force_x_geometry);
|
||||
appConfig_keep_x_running = prefsPrivate.getBoolean(Config.props_keep_x_running, appConfig_keep_x_running);
|
||||
appConfig_run_androidvnc_client = prefsPrivate.getBoolean(Config.props_use_android_vnc, appConfig_run_androidvnc_client);
|
||||
appConfig_xvncbinary_copied = prefsPrivate.getBoolean(Config.props_hasbeencopied, appConfig_xvncbinary_copied);
|
||||
appConfig_height_pixels = prefsPrivate.getInt(Config.props_heightpixels, appConfig_defaultHeightPixels);
|
||||
appConfig_width_pixels = prefsPrivate.getInt(Config.props_widthpixels, appconfig_defaultWidthPixels);
|
||||
appConfig_pocketconfig_copied = prefsPrivate.getBoolean(Config.props_pocketconfigcopied, appConfig_pocketconfig_copied);
|
||||
appConfig_remote_vnc_allowed = prefsPrivate.getBoolean(Config.props_remote_vnc, appConfig_remote_vnc_allowed);
|
||||
appConfig_render = prefsPrivate.getBoolean(Config.props_render, appConfig_render);
|
||||
appConfig_xinerama = prefsPrivate.getBoolean(Config.props_xinerama, appConfig_xinerama);
|
||||
*/
|
||||
}
|
||||
private void save_properties() {
|
||||
/*
|
||||
SharedPreferences prefsPrivate;
|
||||
prefsPrivate = context.getSharedPreferences("PREFS_PRIVATE", Context.MODE_PRIVATE);
|
||||
Editor prefsPrivateEditor = prefsPrivate.edit();
|
||||
prefsPrivateEditor.putBoolean(Config.props_forcexresolution, appConfig_force_x_geometry);
|
||||
prefsPrivateEditor.putBoolean(Config.props_keep_x_running, appConfig_keep_x_running);
|
||||
prefsPrivateEditor.putBoolean(Config.props_use_android_vnc, appConfig_run_androidvnc_client);
|
||||
prefsPrivateEditor.putBoolean(Config.props_hasbeencopied, appConfig_xvncbinary_copied);
|
||||
prefsPrivateEditor.putBoolean(Config.props_pocketconfigcopied, appConfig_pocketconfig_copied);
|
||||
prefsPrivateEditor.putBoolean(Config.props_remote_vnc, appConfig_remote_vnc_allowed);
|
||||
prefsPrivateEditor.putBoolean(Config.props_render, appConfig_render);
|
||||
prefsPrivateEditor.putBoolean(Config.props_xinerama, appConfig_xinerama);
|
||||
prefsPrivateEditor.putInt(Config.props_heightpixels, appConfig_height_pixels);
|
||||
prefsPrivateEditor.putInt(Config.props_widthpixels, appConfig_width_pixels);
|
||||
prefsPrivateEditor.commit();
|
||||
*/
|
||||
}
|
||||
public VncViewer getVncViewer() throws XvncproException {
|
||||
return this.getAndroidvncviewer(); // : this.getPocketcloudvncviewer();
|
||||
}
|
||||
public boolean is_force_x_geometry() {
|
||||
return appConfig_force_x_geometry;
|
||||
}
|
||||
public void set_force_x_geometry(
|
||||
boolean appConfig_force_x_geometry) {
|
||||
Config.appConfig_force_x_geometry = appConfig_force_x_geometry;
|
||||
save_properties();
|
||||
}
|
||||
public boolean is_keep_x_running() {
|
||||
return appConfig_keep_x_running;
|
||||
}
|
||||
public void set_keep_x_running(boolean appConfig_keep_x_running) {
|
||||
Config.appConfig_keep_x_running = appConfig_keep_x_running;
|
||||
save_properties();
|
||||
}
|
||||
public boolean isAppConfig_remote_vnc_allowed() {
|
||||
return appConfig_remote_vnc_allowed;
|
||||
}
|
||||
public void setAppConfig_remote_vnc_allowed(
|
||||
boolean appConfig_remote_vnc_allowed) {
|
||||
Config.appConfig_remote_vnc_allowed = appConfig_remote_vnc_allowed;
|
||||
save_properties();
|
||||
}
|
||||
public int get_height_pixels() {
|
||||
return appConfig_height_pixels;
|
||||
}
|
||||
public void set_height_pixels(int appConfig_height_pixels) {
|
||||
Config.appConfig_height_pixels = appConfig_height_pixels;
|
||||
save_properties();
|
||||
}
|
||||
public int get_width_pixels() {
|
||||
return appConfig_width_pixels;
|
||||
}
|
||||
public void set_width_pixels(int appConfig_width_pixels) {
|
||||
Config.appConfig_width_pixels = appConfig_width_pixels;
|
||||
save_properties();
|
||||
}
|
||||
public int getAppConfig_defaultHeightPixels() {
|
||||
return appConfig_defaultHeightPixels;
|
||||
}
|
||||
public int getAppconfig_defaultWidthPixels() {
|
||||
return appconfig_defaultWidthPixels;
|
||||
}
|
||||
public boolean isAppConfig_render() {
|
||||
return appConfig_render;
|
||||
}
|
||||
public void setAppConfig_render(boolean appConfig_render) {
|
||||
Config.appConfig_render = appConfig_render;
|
||||
save_properties();
|
||||
}
|
||||
public boolean isAppConfig_xinerama() {
|
||||
return appConfig_xinerama;
|
||||
}
|
||||
public void setAppConfig_xinerama(boolean appConfig_xinerama) {
|
||||
Config.appConfig_xinerama = appConfig_xinerama;
|
||||
save_properties();
|
||||
}
|
||||
public VncViewerAndroid getAndroidvncviewer() throws XvncproException {
|
||||
if (activity == null) {
|
||||
throw new XvncproException(context.getString(L.r_xvncpro_activity_notdefined));
|
||||
}
|
||||
androidvncviewer = (androidvncviewer == null) ? new VncViewerAndroid(activity) : androidvncviewer;
|
||||
|
||||
return androidvncviewer;
|
||||
}
|
||||
|
||||
public Handler getUiHandler() {
|
||||
return uiHandler;
|
||||
}
|
||||
public void setUiHandler(Handler mHandler) {
|
||||
Config.uiHandler = mHandler;
|
||||
// getXvnccopy().setuiHandler(mHandler);
|
||||
}
|
||||
public boolean packageInstalled(String packagename) {
|
||||
ApplicationInfo info;
|
||||
try{
|
||||
info = context.getPackageManager().getApplicationInfo(packagename, 0);
|
||||
} catch( PackageManager.NameNotFoundException e ){
|
||||
Log.i(tag, packagename + " is not installed");
|
||||
return false;
|
||||
}
|
||||
Log.i(tag, packagename+" is already installed" + info);
|
||||
return true;
|
||||
}
|
||||
public void installPackage(String packagename) {
|
||||
Log.i(tag, "Requesting installation of "+packagename);
|
||||
Intent goToMarket = new Intent(Intent.ACTION_VIEW).setData(Uri.parse("market://details?id="+packagename));
|
||||
// goToMarket.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
if (activity == null) {
|
||||
Log.i(tag, "Calling installPackage withouth startActivityForResult because activity is null");
|
||||
context.startActivity(goToMarket);
|
||||
} else {
|
||||
Log.d(tag, "Calling installPackage with startActivityForResult because activity is non null");
|
||||
activity.startActivityForResult(goToMarket, INSTALLPACKAGE);
|
||||
}
|
||||
Log.d(tag, "package is installed sending prerrequisite installed for " + packagename);
|
||||
Message m = getUiHandler().obtainMessage(Config.PRERREQUISITEINSTALLED);
|
||||
getUiHandler().sendMessage(m);
|
||||
}
|
||||
public String getTargetdir() {
|
||||
return targetdir;
|
||||
}
|
||||
public void setTargetdir(String targetdir) {
|
||||
Config.targetdir = targetdir;
|
||||
}
|
||||
public static Activity getActivity() {
|
||||
return activity;
|
||||
}
|
||||
public static void setActivity(Activity activity) {
|
||||
Config.activity = activity;
|
||||
}
|
||||
public static boolean isInstallPrerrequisitesOnStart() {
|
||||
return installPrerrequisitesOnStart;
|
||||
}
|
||||
public static void setInstallPrerrequisitesOnStart(
|
||||
boolean finishAfterInstallingPrerrequisites) {
|
||||
Config.installPrerrequisitesOnStart = finishAfterInstallingPrerrequisites;
|
||||
}
|
||||
}
|
||||
80
app/src/main/java/com/theqvd/android/xpro/L.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package com.theqvd.android.xpro;
|
||||
|
||||
//import android.content.Context;
|
||||
//import com.theqvd.android.client.R;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class exists only to highlight the differences between xvncpro and qvdclient
|
||||
*
|
||||
* Copyright 2009-2014 by Qindel Formacion y Servicios S.L.
|
||||
*
|
||||
* xvncpro 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* xvncpro 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.
|
||||
*
|
||||
*
|
||||
* @author Nito@Qindel.ES
|
||||
*
|
||||
*/
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
public final class L
|
||||
{
|
||||
public final static String xvncbinary = "Xvncpro";
|
||||
|
||||
// here is double effort by rewriting R again,
|
||||
public static final int r_dummylayout = R.layout.dummylayout;
|
||||
public static final int r_xvncpromain = R.layout.xvncpromain;
|
||||
public static final int r_xvncmenu = R.menu.xvncmenu;
|
||||
public static final int r_xvncpro_activity_notdefined = R.string.xvncpro_activity_notdefined;
|
||||
|
||||
public static final int r_errorincopytitle = R.string.errorincopytitle;
|
||||
public static final int r_errorincopy = R.string.errorincopy;
|
||||
public static final int r_xvnccopy_not_enough_space = R.string.xvnccopy_not_enough_space;
|
||||
public static final int r_xvnccopy_button_string = R.string.xvnccopy_button_string;
|
||||
public static final int r_xvnccopy_install_string = R.string.xvnccopy_install_string;
|
||||
public static final int r_androidvnc_button_string = R.string.androidvnc_button_string;
|
||||
public static final int r_androidvnc_install_string = R.string.androidvnc_install_string;
|
||||
public static final int r_pocketvnc_button_string = R.string.pocketvnc_button_string;
|
||||
public static final int r_pocketvnc_install_string = R.string.pocketvnc_install_string;
|
||||
public static final int r_installprereqs = R.string.installprereqs;
|
||||
public static final int r_x11_error = R.string.x11_error;
|
||||
public static final int r_x11_is_running = R.string.x11_is_running;
|
||||
public static final int r_ic_xvnc = R.drawable.ic_xvnc;
|
||||
public static final int r_connectionStartButton = R.id.connectionStartButton;
|
||||
public static final int r_stopButton = R.id.stopButton;
|
||||
public static final int r_editText1 = R.id.editText1;
|
||||
public static final int r_editText2 = R.id.editText2;
|
||||
public static final int r_consoletext = R.id.consoletext;
|
||||
public static final int r_toggleForceResolutionButton = R.id.toggleForceResolutionButton;
|
||||
public static final int r_stopOnVncDisconnectButton = R.id.stopOnVncDisconnectButton;
|
||||
public static final int r_vncChoiceButton = R.id.vncChoiceButton;
|
||||
public static final int r_allowRemoteVNCButton = R.id.allowRemoteVNCButton;
|
||||
public static final int r_renderButton = R.id.renderButton;
|
||||
public static final int r_xineramaButton = R.id.xineramaButton;
|
||||
public static final int r_progressbar1 = R.id.progressbar1;
|
||||
public static final int r_helpitem = R.id.helpitem;
|
||||
public static final int r_aboutitem = R.id.aboutitem;
|
||||
public static final int r_changelogitem = R.id.changelogitem;
|
||||
public static final int r_exititem = R.id.exititem;
|
||||
public static final int r_error_handler_message = R.string.error_handler_message;
|
||||
public static final int r_copying = R.string.copying;
|
||||
public static final int r_checkingfiles = R.string.checkingfiles;
|
||||
public static final int r_connect_to_x = R.string.connect_to_x;
|
||||
public static final int r_stopx = R.string.stopx;
|
||||
public static final int r_launchx = R.string.launchx;
|
||||
public static final int r_stopdisabled_not_running = R.string.stopdisabled_not_running;
|
||||
public static final int r_xncpro_helpurl = R.string.xncpro_helpurl;
|
||||
public static final int r_xvncpro_versionName = R.string.xvncpro_versionName;
|
||||
public static final int r_xvncpro_changelogtitle = R.string.xvncpro_changelogtitle;
|
||||
public static final int r_xvncpro_changelog = R.string.xvncpro_changelog;
|
||||
|
||||
|
||||
}
|
||||
25
app/src/main/java/com/theqvd/android/xpro/VncViewer.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.theqvd.android.xpro;
|
||||
/**
|
||||
* Copyright 2009-2014 by Qindel Formacion y Servicios S.L.
|
||||
*
|
||||
* xvncpro 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* xvncpro 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.
|
||||
*
|
||||
*/
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
|
||||
public interface VncViewer /* extends Prerrequisite */ {
|
||||
|
||||
public void launchVncViewer() throws XvncproException;
|
||||
public PendingIntent getContentVncIntent();
|
||||
public Activity getActivity();
|
||||
public void stopVncViewer();
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.theqvd.android.xpro;
|
||||
/**
|
||||
* Copyright 2009-2014 by Qindel Formacion y Servicios S.L.
|
||||
*
|
||||
* xvncpro 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* xvncpro 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.
|
||||
*
|
||||
*/
|
||||
import android.app.*;
|
||||
import android.content.*;
|
||||
import android.graphics.*;
|
||||
import android.net.*;
|
||||
import android.util.*;
|
||||
import net.kdt.pojavlaunch.prefs.*;
|
||||
import android.support.v4.app.*;
|
||||
import android.androidVNC.*;
|
||||
|
||||
public class VncViewerAndroid implements VncViewer {
|
||||
static final String tag = L.xvncbinary + "-VncViewerAndroid-" +java.util.Map.Entry.class.getSimpleName();
|
||||
final static String vncpackage = "android.androidVNC";
|
||||
private static Activity activity;
|
||||
private Config config;
|
||||
PendingIntent contentVncIntent;
|
||||
Intent vncIntent;
|
||||
|
||||
VncViewerAndroid(Activity a) {
|
||||
activity = a;
|
||||
config = new Config(activity);
|
||||
String cmd = Config.vnccmd;
|
||||
vncIntent = new Intent(a, VncCanvasActivity.class);
|
||||
vncIntent.putExtra("x11", Uri.parse(cmd));
|
||||
|
||||
// multiple tasks
|
||||
vncIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
||||
vncIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
||||
|
||||
// Remove old Create new task
|
||||
// vncIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
contentVncIntent = PendingIntent.getActivity(activity, 0, vncIntent, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launchVncViewer() {
|
||||
Log.i(tag, "launching vncviewer androidvnc with activity="+activity+"; vncIntent="+vncIntent);
|
||||
Intent intent = (Intent) vncIntent.clone();
|
||||
if (LauncherPreferences.PREF_FREEFORM) {
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
|
||||
ActivityOptionsCompat options = ActivityOptionsCompat.makeBasic();
|
||||
Rect freeformRect = new Rect(0, 0, dm.widthPixels / 2, dm.heightPixels / 2);
|
||||
options.setLaunchBounds(freeformRect);
|
||||
activity.startActivityForResult(intent, Config.vncActivityRequestCode, options.toBundle());
|
||||
} else {
|
||||
activity.startActivityForResult(intent, Config.vncActivityRequestCode);
|
||||
}
|
||||
// activity.startActivityForResult(intent, Config.vncActivityRequestCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopVncViewer() {
|
||||
Log.i(tag, "Stopping activity with activity code " + Config.vncActivityRequestCode);
|
||||
|
||||
activity.finishActivity(Config.vncActivityRequestCode);
|
||||
}
|
||||
@Override
|
||||
public PendingIntent getContentVncIntent() {
|
||||
return contentVncIntent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
return activity;
|
||||
}
|
||||
|
||||
}
|
||||
331
app/src/main/java/com/theqvd/android/xpro/XserverService.java
Normal file
@@ -0,0 +1,331 @@
|
||||
package com.theqvd.android.xpro;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class represents an XserverService
|
||||
*
|
||||
*
|
||||
* Copyright 2009-2014 by Qindel Formacion y Servicios S.L.
|
||||
*
|
||||
* xvncpro 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* xvncpro 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.
|
||||
*
|
||||
* @author nito
|
||||
*
|
||||
*/
|
||||
public class XserverService extends Service
|
||||
implements Runnable
|
||||
{
|
||||
final static String tag = L.xvncbinary + "-XserverService-" +java.util.Map.Entry.class.getSimpleName();
|
||||
private Thread aThread;
|
||||
private static Process process;
|
||||
static private boolean xserverrunning = false;
|
||||
static private int pid = -1;
|
||||
private Config config;
|
||||
static private XserverService instance = null;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
Log.i(tag, "onCreate");
|
||||
super.onCreate();
|
||||
config = new Config(this);
|
||||
instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Log.i(tag, "Received start id " + startId + ": " + intent);
|
||||
super.onStartCommand(intent, flags, startId);
|
||||
|
||||
if (isRunning()) {
|
||||
launchVNC();
|
||||
return START_STICKY;
|
||||
}
|
||||
aThread = new Thread (this);
|
||||
aThread.start();
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
private void stopXvnc() {
|
||||
if (isRunning()) {
|
||||
Log.i(tag, "stop pid " + getPid());
|
||||
process.destroy();
|
||||
android.os.Process.killProcess(getPid());
|
||||
setRunning(false);
|
||||
setPid(-1);
|
||||
android.os.Process.sendSignal(getPid(), android.os.Process.SIGNAL_QUIT);
|
||||
updateButtons();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log.i(tag, "onDestroy");
|
||||
stopVNC();
|
||||
if (isRunning()) {
|
||||
Log.i(tag, "onDestroy xserverrunning destroy " + getPid());
|
||||
stopXvnc();
|
||||
}
|
||||
|
||||
cancelNotify();
|
||||
updateButtons();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent arg0) {
|
||||
Log.i(tag, "onBind");
|
||||
return null;
|
||||
}
|
||||
|
||||
private void launchVNC() {
|
||||
VncViewer v;
|
||||
try {
|
||||
v = config.getVncViewer();
|
||||
v.launchVncViewer();
|
||||
} catch (XvncproException e) {
|
||||
sendNotify(getString(L.r_x11_error), "Pid:"+e.toString());
|
||||
}
|
||||
}
|
||||
private void stopVNC() {
|
||||
VncViewer v;
|
||||
try {
|
||||
v = config.getVncViewer();
|
||||
v.stopVncViewer();
|
||||
} catch (XvncproException e) {
|
||||
sendNotify(getString(L.r_x11_error), "Pid:"+e.toString());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
String cmd = Config.xvnccmd+" -geometry "+ config.get_width_pixels() + "x" + config.get_height_pixels();
|
||||
cmd += config.isAppConfig_remote_vnc_allowed() ? "" : " " + Config.notAllowRemoteVncConns;
|
||||
cmd += config.isAppConfig_render() ? " +render" : "";
|
||||
cmd += config.isAppConfig_xinerama() ? " +xinerama" : "";
|
||||
Log.i(tag, "launching:"+cmd);
|
||||
String cmdList[] = cmd.split("[ ]+");
|
||||
try {
|
||||
process = new ProcessBuilder().command(cmdList).redirectErrorStream(true).start();
|
||||
setPid(parsePid(process));
|
||||
setRunning(true);
|
||||
isRunning();
|
||||
Log.i(tag, "after launch:<"+cmd+"> = "+process.toString() + "," + process.hashCode() + "," + process.getClass());
|
||||
InputStream in = process.getInputStream();
|
||||
InputStreamReader isr = new InputStreamReader(in);
|
||||
BufferedReader br = new BufferedReader(isr, 128);
|
||||
String line;
|
||||
|
||||
while ((line = br.readLine()) != null) {
|
||||
Log.d(tag, "Read string <"+line+">");
|
||||
if (line.matches(Config.serverstartedstring)) {
|
||||
Log.i(tag, "Found string <"+line+"> launching VNC client");
|
||||
launchVNC();
|
||||
updateButtons();
|
||||
}
|
||||
// For AndroidVNC error see
|
||||
// See http://code.google.com/p/android-vnc-viewer/issues/detail?id=299
|
||||
if (line.matches(Config.vncdisconnectedstring)) {
|
||||
Log.i(tag, "Found string <"+line+">");
|
||||
stopVNC();
|
||||
if (!config.is_keep_x_running()) {
|
||||
Log.i(tag, "Stopping Xvnc service");
|
||||
stopXvnc();
|
||||
this.stopSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
process.waitFor();
|
||||
Log.i(tag, "Xvnc Process has died");
|
||||
} catch (IOException e) {
|
||||
Log.e(tag, "IOException:"+e.toString());
|
||||
sendNotify(getString(L.r_x11_error), "Pid:"+e.toString());
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(tag, "InterruptedException:"+e.toString());
|
||||
sendNotify(getString(L.r_x11_error), "Pid:"+e.toString());
|
||||
} finally {
|
||||
if (!config.is_keep_x_running()) {
|
||||
Log.i(tag, "Stopping Xvnc service (step 2)");
|
||||
stopXvnc();
|
||||
stopVNC();
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
private static int parsePid(Process p) {
|
||||
int pid;
|
||||
String s = p.toString();
|
||||
Log.d(tag, "parsePid for process String <"+s+">");
|
||||
Pattern pattern = Pattern.compile("id=([0-9]+)[^0-9].*$");
|
||||
|
||||
Matcher m = pattern.matcher(s);
|
||||
if (m.find()) {
|
||||
Log.d(tag, "Pattern <"+pattern+"> found in string " + s + " with matching part "+m.group(1));
|
||||
pid = Integer.parseInt(m.group(1));
|
||||
} else
|
||||
{
|
||||
Log.e(tag, "Pattern <"+pattern+"> not found in string " + s + ". Trouble ahead when stopping");
|
||||
pid = -1;
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
public int getPid() {
|
||||
return pid;
|
||||
}
|
||||
private void setPid(int pid) {
|
||||
Log.d(tag, "Setting pid to " + pid);
|
||||
XserverService.pid = pid;
|
||||
}
|
||||
|
||||
private static int searchForXvncPid() {
|
||||
String psoutput = "";
|
||||
int pidfound = -1;
|
||||
String cmd = Config.psxvnccmd;
|
||||
String cmdList[] = cmd.split("[ ]+");
|
||||
try {
|
||||
process = new ProcessBuilder().command(cmdList).redirectErrorStream(true).start();
|
||||
Log.i(tag, "after launch:<"+cmd+"> = "+process.toString() + "," + process.hashCode() + "," + process.getClass());
|
||||
InputStream in = process.getInputStream();
|
||||
InputStreamReader isr = new InputStreamReader(in);
|
||||
BufferedReader br = new BufferedReader(isr);
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
psoutput += line + "\n";
|
||||
Log.d(tag, "Read string <"+line+">");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(tag, "Error executing <"+cmd+"> "+e.toString());
|
||||
return pidfound;
|
||||
}
|
||||
|
||||
Pattern pattern = Pattern.compile("(?m)^\\S+\\s+(\\d+)\\s+.*?"+L.xvncbinary+"$");
|
||||
|
||||
Matcher m = pattern.matcher(psoutput);
|
||||
if (m.find()) {
|
||||
Log.d(tag, "Pattern <"+pattern+"> found in string <" + psoutput + "> with matching part "+m.group(1));
|
||||
pidfound = Integer.parseInt(m.group(1));
|
||||
} else
|
||||
{
|
||||
Log.d(tag, "Pattern <"+pattern+"> not found in string <" + psoutput + ">");
|
||||
}
|
||||
return pidfound;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
Log.d(tag, "Running is "+xserverrunning + " pid="+pid);
|
||||
if (XserverService.xserverrunning) {
|
||||
File file=new File("/proc/" + pid);
|
||||
boolean exists = file.exists();
|
||||
if (exists) {
|
||||
sendNotify(getString(L.r_x11_is_running), "Pid:"+XserverService.pid);
|
||||
return XserverService.xserverrunning;
|
||||
}
|
||||
// Pid no longer there
|
||||
Log.i(tag, "The process was supposed to be running but pid "+pid+" is no longer there, setting running to false");
|
||||
}
|
||||
XserverService.pid=searchForXvncPid();
|
||||
XserverService.xserverrunning = (XserverService.pid != -1);
|
||||
if (XserverService.xserverrunning) {
|
||||
sendNotify(getString(L.r_x11_is_running), "Pid:"+XserverService.pid);
|
||||
} else {
|
||||
cancelNotify();
|
||||
}
|
||||
return XserverService.xserverrunning;
|
||||
}
|
||||
private void setRunning(boolean value) {
|
||||
Log.d(tag, "Setting xserverrunning to "+value);
|
||||
XserverService.xserverrunning = value;
|
||||
updateButtons();
|
||||
}
|
||||
private void updateButtons() {
|
||||
Log.d(tag, "message updateButtons");
|
||||
if (config.getUiHandler() == null) {
|
||||
Log.d(tag, "message updateButtons not sent because uiHandler is null");
|
||||
return;
|
||||
}
|
||||
Message m = config.getUiHandler().obtainMessage(Config.UPDATEBUTTONS);
|
||||
config.getUiHandler().sendMessage(m);
|
||||
}
|
||||
|
||||
private void sendAlert(String title, String text) {
|
||||
Log.d(tag, "message sendAlert");
|
||||
if (config.getUiHandler() == null) {
|
||||
Log.d(tag, "message sendAlert not sent because uiHandler is null");
|
||||
return;
|
||||
}
|
||||
|
||||
Message m = config.getUiHandler().obtainMessage(Config.SENDALERT);
|
||||
Bundle b = new Bundle();
|
||||
b.putString(Config.messageTitle, title);
|
||||
b.putString(Config.messageText, text);
|
||||
m.setData(b);
|
||||
config.getUiHandler().sendMessage(m);
|
||||
}
|
||||
public static XserverService getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
//@SuppressWarnings("deprecation")
|
||||
private void sendNotify(CharSequence title, CharSequence text) {
|
||||
Context c = this.getApplicationContext();
|
||||
// TODO try to set the DummyActivity as the intent
|
||||
// Intent dummyactivity = new Intent(this, DummyActivity.class);
|
||||
// dummyactivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
// PendingIntent i = PendingIntent.getActivity(c, 0, new Intent(), 0);
|
||||
// End of TODO
|
||||
PendingIntent i = null;
|
||||
if (config == null) {
|
||||
Log.i(tag, "Not sending notify because config is null. This should not happen");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
i = config.getVncViewer().getContentVncIntent();
|
||||
Log.i(tag, "activity is "+c+" intent is "+i);
|
||||
} catch (XvncproException e) {
|
||||
Log.e(tag, "Vnc intent error "+e.toString());
|
||||
}
|
||||
|
||||
if (config == null) {
|
||||
Log.i(tag, "Not sending notify because config, vncViewer, or context is null");
|
||||
return;
|
||||
}
|
||||
if (i == null) {
|
||||
Log.e(tag, "PendingIntent is null creating empty PendingIntent");
|
||||
i = PendingIntent.getActivity(c, 0, new Intent(), 0);
|
||||
}
|
||||
Notification notification = new Notification(L.r_ic_xvnc, title, System.currentTimeMillis());
|
||||
notification.setLatestEventInfo(c, title, text, i);
|
||||
NotificationManager nm = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(Config.notifystartx, notification);
|
||||
Log.i(tag, "Sent notify with id <"+Config.notifystartx+">title <" +title+"> and text <" + text +">");
|
||||
}
|
||||
public void cancelNotify() {
|
||||
NotificationManager nm = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.cancel(Config.notifystartx);
|
||||
Log.i(tag, "Cancelled notify with id <" +Config.notifystartx+">");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.theqvd.android.xpro;
|
||||
|
||||
/**
|
||||
* Copyright 2009-2014 by Qindel Formacion y Servicios S.L.
|
||||
*
|
||||
* xvncpro 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* xvncpro 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.
|
||||
*
|
||||
*/
|
||||
|
||||
public class XvncproException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public XvncproException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,8 @@ import android.support.design.widget.*;
|
||||
import android.support.v4.app.*;
|
||||
import android.support.v4.view.*;
|
||||
import android.support.v7.app.*;
|
||||
import android.util.*;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import android.widget.AdapterView.*;
|
||||
@@ -34,6 +35,8 @@ import android.graphics.*;
|
||||
import android.content.pm.*;
|
||||
import android.text.*;
|
||||
import com.kdt.mcgui.*;
|
||||
import com.theqvd.android.xpro.*;
|
||||
import android.net.*;
|
||||
|
||||
public class MCLauncherActivity extends AppCompatActivity
|
||||
{
|
||||
@@ -620,26 +623,29 @@ public class MCLauncherActivity extends AppCompatActivity
|
||||
crashView.setLastCrash("");
|
||||
|
||||
try {
|
||||
/*
|
||||
List<String> jvmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments();
|
||||
jvmArgs.add("-Xms128M");
|
||||
jvmArgs.add("-Xmx1G");
|
||||
*/
|
||||
Intent mainIntent = new Intent(MCLauncherActivity.this, MainConsoleActivity.class);
|
||||
// mainIntent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
|
||||
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
||||
mainIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
||||
Intent vncIntent = new Intent(MCLauncherActivity.this, android.androidVNC.VncCanvasActivity.class);
|
||||
vncIntent.putExtra("x11", Uri.parse(Config.vnccmd));
|
||||
|
||||
// multiple tasks
|
||||
vncIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
||||
vncIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
||||
|
||||
if (LauncherPreferences.PREF_FREEFORM) {
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
|
||||
ActivityOptions options = (ActivityOptions) ActivityOptions.class.getMethod("makeBasic").invoke(null);
|
||||
ActivityOptionsCompat options = ActivityOptionsCompat.makeBasic();
|
||||
Rect freeformRect = new Rect(0, 0, dm.widthPixels / 2, dm.heightPixels / 2);
|
||||
options.getClass().getDeclaredMethod("setLaunchBounds", Rect.class).invoke(options, freeformRect);
|
||||
startActivity(mainIntent, options.toBundle());
|
||||
options.setLaunchBounds(freeformRect);
|
||||
startActivityForResult(vncIntent, Config.vncActivityRequestCode, options.toBundle());
|
||||
} else {
|
||||
startActivity(mainIntent);
|
||||
startActivityForResult(vncIntent, Config.vncActivityRequestCode);
|
||||
}
|
||||
|
||||
// Intent mainIntent = new Intent(MCLauncherActivity.this, MainConsoleActivity.class);
|
||||
// mainIntent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
|
||||
|
||||
|
||||
}
|
||||
catch (Throwable e) {
|
||||
Tools.showError(MCLauncherActivity.this, e);
|
||||
@@ -654,12 +660,11 @@ public class MCLauncherActivity extends AppCompatActivity
|
||||
mTask = null;
|
||||
}
|
||||
|
||||
private Gson gsonss = gson;
|
||||
public static final String MINECRAFT_RES = "http://resources.download.minecraft.net/";
|
||||
|
||||
public JAssets downloadIndex(String versionName, File output) throws Exception {
|
||||
String versionJson = DownloadUtils.downloadString("http://s3.amazonaws.com/Minecraft.Download/indexes/" + versionName + ".json");
|
||||
JAssets version = gsonss.fromJson(versionJson, JAssets.class);
|
||||
JAssets version = gson.fromJson(versionJson, JAssets.class);
|
||||
output.getParentFile().mkdirs();
|
||||
Tools.write(output.getAbsolutePath(), versionJson.getBytes(Charset.forName("UTF-8")));
|
||||
return version;
|
||||
|
||||
@@ -17,6 +17,7 @@ import android.graphics.*;
|
||||
import android.view.*;
|
||||
import android.text.method.*;
|
||||
import net.kdt.pojavlaunch.prefs.*;
|
||||
import net.kdt.pojavlaunch.value.*;
|
||||
|
||||
public class MainConsoleActivity extends AppCompatActivity
|
||||
{
|
||||
@@ -83,6 +84,13 @@ public class MainConsoleActivity extends AppCompatActivity
|
||||
|
||||
private void launchJava(String modPath) {
|
||||
try {
|
||||
/*
|
||||
* 17w43a and above change Minecraf arguments from
|
||||
* `minecraftArguments` to `arguments` so check if
|
||||
* selected version requires LWJGL 3 or not is easy.
|
||||
*/
|
||||
boolean isLwjgl3 = mVersionInfo.arguments != null;
|
||||
|
||||
List<String> mJreArgs = new ArrayList<String>();
|
||||
mJreArgs.add("java");
|
||||
mJreArgs.add("-Duser.home=" + Tools.MAIN_PATH);
|
||||
@@ -111,6 +119,7 @@ public class MainConsoleActivity extends AppCompatActivity
|
||||
* Useful if enable root mode */
|
||||
process.writeToProcess("chmod -R 700 " + Tools.homeJreDir);
|
||||
process.writeToProcess("cd " + Tools.MAIN_PATH);
|
||||
process.writeToProcess("export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/minecraft_lib/lwjgl" + (isLwjgl3 ? "3" : "2"));
|
||||
process.writeToProcess(mJreArgs.toArray(new String[0]));
|
||||
} catch (Throwable th) {
|
||||
th.printStackTrace();
|
||||
|
||||
@@ -445,9 +445,12 @@ public class PojavLoginActivity extends MineActivity
|
||||
// Extract launcher_profiles.json
|
||||
// TODO: Remove after implement.
|
||||
Tools.copyAssetFile(this, "launcher_profiles.json", Tools.MAIN_PATH, false);
|
||||
|
||||
Tools.copyAssetFile(this, "ClassWrapper.jar", Tools.libraries, true);
|
||||
|
||||
try {
|
||||
Os.symlink(Tools.homeJreDir, Tools.datapath + "/xvncfiles");
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
// Yep, the codebase from v1.0.3:
|
||||
//FileAccess.copyAssetToFolderIfNonExist(this, "1.0.jar", Tools.versnDir + "/1.0");
|
||||
//FileAccess.copyAssetToFolderIfNonExist(this, "1.7.3.jar", Tools.versnDir + "/1.7.3");
|
||||
|
||||
@@ -20,6 +20,10 @@ public class SimpleShellProcess
|
||||
); //"/system/bin/sh -c \"" + command + "\"");
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
process.destroy();
|
||||
}
|
||||
|
||||
public void writeToProcess(String[] args) throws IOException {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
|
||||
@@ -14,11 +14,6 @@ public class LauncherPreferenceFragment extends PreferenceFragmentCompat
|
||||
// Disable freeform mode in Android 6.0 or below.
|
||||
findPreference("freeform").setEnabled(Build.VERSION.SDK_INT >= 24);
|
||||
|
||||
SeekBarPreference seek1 = (SeekBarPreference) findPreference("maxDxRefs");
|
||||
seek1.setMin(0xFFF);
|
||||
seek1.setMax(0xFFFF);
|
||||
seek1.setValue(0xFFF);
|
||||
|
||||
SeekBarPreference seek2 = (SeekBarPreference) findPreference("timeLongPressTrigger");
|
||||
seek2.setMin(100);
|
||||
seek2.setMax(1000);
|
||||
|
||||
BIN
app/src/main/res/drawable-hdpi/ic_xvnc.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
app/src/main/res/drawable-hdpi/mouse_icon.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
app/src/main/res/drawable-ldpi/ic_xvnc.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable-ldpi/mouse_icon.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable-mdpi/ic_xvnc.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/drawable-mdpi/mouse_icon.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_xvnc.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
app/src/main/res/drawable-xhdpi/mouse_icon.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |