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