/**
* 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;
}
}