Added the desktop image scaling support to vncviewer.

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@579 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index e49b725..c7b496b 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -220,7 +220,7 @@
   clipboard.setNotifier(this);
 
   // Create the backing buffer
-  buffer = new win32::DIBSectionBuffer(frameHandle);
+  buffer = new win32::ScaledDIBSectionBuffer(frameHandle);
 
   // Show the window
   centerWindow(handle, 0);
@@ -774,8 +774,10 @@
           break;
 
         // Send a pointer event to the server
-        ptr.pointerEvent(callback, p, mask);
         oldpos = p;
+        p.x /= double(buffer->getScale()) / 100;
+        p.y /= double(buffer->getScale()) / 100;
+        ptr.pointerEvent(callback, p, mask);
 #ifdef WM_MOUSEWHEEL
       }
 #endif
@@ -795,8 +797,8 @@
   // *** ALWAYS call this BEFORE changing buffer PF!!!
   if (cursorVisible) {
     cursorVisible = false;
-    buffer->imageRect(cursorBackingRect, cursorBacking.data);
-    invalidateDesktopRect(cursorBackingRect);
+    buffer->DIBSectionBuffer::imageRect(cursorBackingRect, cursorBacking.data);
+    invalidateDesktopRect(cursorBackingRect, false);
   }
 }
 
@@ -818,7 +820,7 @@
 
     renderLocalCursor();
 
-    invalidateDesktopRect(cursorBackingRect);
+    invalidateDesktopRect(cursorBackingRect, false);
   }
 }
 
@@ -834,7 +836,7 @@
 {
   Rect r = cursor.getRect();
   r = r.translate(cursorPos).translate(cursor.hotspot.negate());
-  buffer->maskRect(r, cursor.data, cursor.mask.buf);
+  buffer->DIBSectionBuffer::maskRect(r, cursor.data, cursor.mask.buf);
 }
 
 void
@@ -857,8 +859,11 @@
 
 
 bool
-DesktopWindow::invalidateDesktopRect(const Rect& crect) {
-  Rect rect = desktopToClient(crect);
+DesktopWindow::invalidateDesktopRect(const Rect& crect, bool scaling) {
+  Rect rect;
+  if (buffer->isScaling() && scaling) {
+    rect = desktopToClient(buffer->calculateScaleBoundary(crect));
+  } else rect = desktopToClient(crect);
   if (rect.intersect(client_size).is_empty()) return false;
   RECT invalid = {rect.tl.x, rect.tl.y, rect.br.x, rect.br.y};
   InvalidateRect(frameHandle, &invalid, FALSE);
@@ -1059,18 +1064,21 @@
 
 
 void DesktopWindow::fillRect(const Rect& r, Pixel pix) {
-  if (cursorBackingRect.overlaps(r)) hideLocalCursor();
+  Rect img_rect = buffer->isScaling() ? buffer->calculateScaleBoundary(r) : r;
+  if (cursorBackingRect.overlaps(img_rect)) hideLocalCursor();
   buffer->fillRect(r, pix);
   invalidateDesktopRect(r);
 }
 void DesktopWindow::imageRect(const Rect& r, void* pixels) {
-  if (cursorBackingRect.overlaps(r)) hideLocalCursor();
+  Rect img_rect = buffer->isScaling() ? buffer->calculateScaleBoundary(r) : r;
+  if (cursorBackingRect.overlaps(img_rect)) hideLocalCursor();
   buffer->imageRect(r, pixels);
   invalidateDesktopRect(r);
 }
 void DesktopWindow::copyRect(const Rect& r, int srcX, int srcY) {
-  if (cursorBackingRect.overlaps(r) ||
-      cursorBackingRect.overlaps(Rect(srcX, srcY, srcX+r.width(), srcY+r.height())))
+  Rect img_rect = buffer->isScaling() ? buffer->calculateScaleBoundary(r) : r;
+  if (cursorBackingRect.overlaps(img_rect) ||
+      cursorBackingRect.overlaps(Rect(srcX, srcY, srcX+img_rect.width(), srcY+img_rect.height())))
     hideLocalCursor();
   buffer->copyRect(r, Point(r.tl.x-srcX, r.tl.y-srcY));
   invalidateDesktopRect(r);
@@ -1078,7 +1086,8 @@
 
 void DesktopWindow::invertRect(const Rect& r) {
   int stride;
-  rdr::U8* p = buffer->getPixelsRW(r, &stride);
+  rdr::U8* p = buffer->isScaling() ? buffer->getPixelsRW(buffer->calculateScaleBoundary(r), &stride) 
+   : buffer->getPixelsRW(r, &stride);
   for (int y = 0; y < r.height(); y++) {
     for (int x = 0; x < r.width(); x++) {
       switch (buffer->getPF().bpp) {
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
index d54cd5f..3d2211f 100644
--- a/vncviewer/DesktopWindow.h
+++ b/vncviewer/DesktopWindow.h
@@ -34,7 +34,7 @@
 #include <rfb_win32/CKeyboard.h>
 #include <rfb_win32/CPointer.h>
 #include <rfb_win32/Clipboard.h>
-#include <rfb_win32/DIBSectionBuffer.h>
+#include <rfb_win32/ScaledDIBSectionBuffer.h>
 #include <rfb_win32/LogicalPalette.h>
 #include <vncviewer/ViewerToolBar.h>
 
@@ -195,7 +195,7 @@
       void cursorOutsideBuffer();
 
       // Returns true if part of the supplied rect is visible, false otherwise
-      bool invalidateDesktopRect(const Rect& crect);
+      bool invalidateDesktopRect(const Rect& crect, bool scaling=true);
 
       // Determine whether or not we need to enable/disable scrollbars and set the
       // window style accordingly
@@ -232,7 +232,7 @@
       bool showToolbar;
 
       // Local window state
-      win32::DIBSectionBuffer* buffer;
+      win32::ScaledDIBSectionBuffer* buffer;
       bool has_focus;
       Rect window_size;
       Rect client_size;