/* (non-Javadoc)
  * @see com.iiordanov.bVNC.AbstractBitmapData#prepareFullUpdateRequest(boolean)
  */
 @Override
 public synchronized void prepareFullUpdateRequest(boolean incremental) {
   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);
   }
 }
 /* (non-Javadoc)
  * @see com.iiordanov.bVNC.AbstractBitmapData#validDraw(int, int, int, int)
  */
 @Override
 public synchronized boolean validDraw(int x, int y, int w, int h) {
   boolean result =
       x - xoffset >= 0
           && x - xoffset + w <= bitmapwidth
           && y - yoffset >= 0
           && y - yoffset + h <= bitmapheight;
   // android.util.Log.e("LBM", "Validate Drawing x:"+x+" y:"+y+" w:"+w+" h:"+h+" xoff:"+xoffset+"
   // yoff:"+yoffset+" "+(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 com.iiordanov.bVNC.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) {
        mbitmap.eraseColor(Color.GREEN);
        vncCanvas.writeFullUpdateRequest(false);
      }
    }
    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);
      rfb.writeFramebufferUpdateRequest(
          invalidRect.left,
          invalidRect.top,
          invalidRect.right - invalidRect.left,
          invalidRect.bottom - invalidRect.top,
          false);
      pendingList.add(invalidRect);
    }
    waitingForInput = true;
    // android.util.Log.i("LBM", "pending "+pendingList.toString() + "invalid
    // "+invalidList.toString());
  }