/** * Copyright (C) 2012 Iordan Iordanov * Copyright (C) 2009 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.iiordanov.bVNC; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; class CompactBitmapData 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 = 7; boolean isSpice = false; Bitmap.Config cfg = Bitmap.Config.RGB_565; 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) { try { synchronized (mbitmap) { canvas.drawBitmap(data.mbitmap, 0.0f, 0.0f, _defaultPaint); canvas.drawBitmap(softCursor, cursorRect.left, cursorRect.top, _defaultPaint); } } catch (Throwable e) { } } } CompactBitmapData(RfbConnectable rfb, RemoteCanvas c, boolean trueColor) { super(rfb,c); bitmapwidth=framebufferwidth; bitmapheight=framebufferheight; // To please createBitmap, we ensure the size it at least 1x1. if (bitmapwidth == 0) bitmapwidth = 1; if (bitmapheight == 0) bitmapheight = 1; if (trueColor) cfg = Bitmap.Config.ARGB_8888; mbitmap = Bitmap.createBitmap(bitmapwidth, bitmapheight, cfg); mbitmap.setHasAlpha(false); memGraphics = new Canvas(mbitmap); bitmapPixels = new int[bitmapwidth * bitmapheight]; drawable.startDrawing(); } @Override public boolean validDraw(int x, int y, int w, int h) { return true; } @Override public int offset(int x, int y) { return y * bitmapwidth + x; } /* (non-Javadoc) * @see com.iiordanov.bVNC.AbstractBitmapData#createDrawable() */ @Override AbstractBitmapDrawable createDrawable() { return new CompactBitmapDrawable(); } /* (non-Javadoc) * @see com.iiordanov.bVNC.AbstractBitmapData#updateBitmap(int, int, int, int) */ @Override public void updateBitmap(int x, int y, int w, int h) { synchronized (mbitmap) { mbitmap.setPixels(bitmapPixels, offset(x,y), bitmapwidth, x, y, w, h); } } /* (non-Javadoc) * @see com.iiordanov.bVNC.AbstractBitmapData#updateBitmap(Bitmap, int, int, int, int) */ @Override public void updateBitmap(Bitmap b, int x, int y, int w, int h) { synchronized (mbitmap) { memGraphics.drawBitmap(b, x, y, null); } } /* (non-Javadoc) * @see com.iiordanov.bVNC.AbstractBitmapData#copyRect(android.graphics.Rect, android.graphics.Rect, android.graphics.Paint) */ @Override public void copyRect(int sx, int sy, int dx, int dy, int w, int h) { int srcOffset, dstOffset; int dstH = h; int dstW = w; int startSrcY, endSrcY, dstY, deltaY; if (sy > dy) { startSrcY = sy; endSrcY = sy + dstH; dstY = dy; deltaY = +1; } else { startSrcY = sy + dstH - 1; endSrcY = sy - 1; dstY = dy + dstH - 1; deltaY = -1; } for (int y = startSrcY; y != endSrcY; y += deltaY) { srcOffset = offset(sx, y); dstOffset = offset(dx, dstY); try { synchronized (mbitmap) { mbitmap.getPixels(bitmapPixels, srcOffset, bitmapwidth, sx-xoffset, y-yoffset, dstW, 1); } System.arraycopy(bitmapPixels, srcOffset, bitmapPixels, dstOffset, dstW); } catch (Exception e) { // There was an index out of bounds exception, but we continue copying what we can. e.printStackTrace(); } dstY += deltaY; } updateBitmap(dx, dy, dstW, dstH); } /* (non-Javadoc) * @see com.iiordanov.bVNC.AbstractBitmapData#drawRect(int, int, int, int, android.graphics.Paint) */ @Override void drawRect(int x, int y, int w, int h, Paint paint) { synchronized (mbitmap) { memGraphics.drawRect(x, y, x + w, y + h, paint); } } /* (non-Javadoc) * @see com.iiordanov.bVNC.AbstractBitmapData#scrollChanged(int, int) */ @Override void scrollChanged(int newx, int newy) { // Don't need to do anything here } /* (non-Javadoc) * @see com.iiordanov.bVNC.AbstractBitmapData#frameBufferSizeChanged(RfbProto) */ @Override public void frameBufferSizeChanged () { framebufferwidth=rfb.framebufferWidth(); framebufferheight=rfb.framebufferHeight(); android.util.Log.i("CBM", "bitmapsize changed = ("+bitmapwidth+","+bitmapheight+")"); if ( bitmapwidth < framebufferwidth || bitmapheight < framebufferheight ) { dispose(); // Try to free up some memory. System.gc(); bitmapwidth = framebufferwidth; bitmapheight = framebufferheight; bitmapPixels = new int[bitmapwidth * bitmapheight]; mbitmap = Bitmap.createBitmap(bitmapwidth, bitmapheight, cfg); memGraphics = new Canvas(mbitmap); drawable = createDrawable(); drawable.startDrawing(); } } /* (non-Javadoc) * @see com.iiordanov.bVNC.AbstractBitmapData#syncScroll() */ @Override void syncScroll() { // Don't need anything here either } }