Additional changes to support scroll panes whether an applet is running in its own frame or on an html page. Some resizing support.

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2535 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/java/src/com/tightvnc/rfbplayer/RfbPlayer.java b/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
index c46c769..4b74889 100644
--- a/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
+++ b/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
@@ -31,6 +31,11 @@
   boolean inAnApplet = true;
   boolean inSeparateFrame = false;
 
+  /** current applet width */
+  int dispW = 300;
+  /** current applet height */
+  int dispH = 200;
+
   //
   // main() is called when run as a java program from the command line.
   // It simply runs the applet inside a newly-created frame.
@@ -133,34 +138,36 @@
       gbc.weightx = 1.0;
       gbc.weighty = 1.0;
 
+      // Create a panel which itself is resizeable and can hold
+      // non-resizeable VncCanvas component at the top left corner.
+      Panel canvasPanel = new Panel();
+      canvasPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
+      canvasPanel.add(vc);
+
+      // Create a ScrollPane which will hold a panel with VncCanvas
+      // inside.
+      desktopScrollPane = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
+      gbc.fill = GridBagConstraints.BOTH;
+      gridbag.setConstraints(canvasPanel, gbc);
+      desktopScrollPane.add(canvasPanel);
+
+      // Now add the scroll bar to the container.
       if (inSeparateFrame) {
-
-        // Create a panel which itself is resizeable and can hold
-        // non-resizeable VncCanvas component at the top left corner.
-        Panel canvasPanel = new Panel();
-        canvasPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
-        canvasPanel.add(vc);
-
-        // Create a ScrollPane which will hold a panel with VncCanvas
-        // inside.
-        desktopScrollPane = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
-        gbc.fill = GridBagConstraints.BOTH;
         gridbag.setConstraints(desktopScrollPane, gbc);
-        desktopScrollPane.add(canvasPanel);
-
-        // Finally, add our ScrollPane to the Frame window.
         vncFrame.add(desktopScrollPane);
         vncFrame.setTitle(rfb.desktopName);
         vncFrame.pack();
         vc.resizeDesktopFrame();
-
       } else {
+        // Size the scroll pane to display size.
+        desktopScrollPane.setSize(dispW, dispH);
 
         // Just add the VncCanvas component to the Applet.
-        gridbag.setConstraints(vc, gbc);
-        add(vc);
+        gbc.fill = GridBagConstraints.NONE;
+        gridbag.setConstraints(desktopScrollPane, gbc);
+        add(desktopScrollPane);
         validate();
-
+        vc.resizeEmbeddedApplet();
       }
 
       while (true) {
@@ -271,6 +278,10 @@
     deferScreenUpdates = (int)readLongParameter("Defer screen updates", 20);
     if (deferScreenUpdates < 0)
       deferScreenUpdates = 0;	// Just in case.
+
+    // Display width and height.
+    dispW = readIntParameter("DISPLAY_WIDTH", dispW);
+    dispH = readIntParameter("DISPLAY_HEIGHT", dispH);
   }
 
   public String readParameter(String name, boolean required) {
@@ -324,6 +335,18 @@
     return result;
   }
 
+  int readIntParameter(String name, int defaultValue) {
+    String str = readParameter(name, false);
+    int result = defaultValue;
+    if (str != null) {
+      try {
+        result = Integer.parseInt(str);
+      } catch (NumberFormatException e) {
+      }
+    }
+    return result;
+  }
+
   //
   // fatalError() - print out a fatal error message.
   //
@@ -364,6 +387,17 @@
     }
   }
 
+  //
+  // Set the new width and height of the applet. Call when browser is resized to 
+  // resize the viewer.
+  //
+  public void displaySize(int width, int height) {
+    dispW = width;
+    dispH = height;
+    if (!inSeparateFrame) {
+      vc.resizeEmbeddedApplet();
+    }
+  }
 
   //
   // Close application properly on window close event.
diff --git a/java/src/com/tightvnc/rfbplayer/VncCanvas.java b/java/src/com/tightvnc/rfbplayer/VncCanvas.java
index 48d0f6d..b369c63 100644
--- a/java/src/com/tightvnc/rfbplayer/VncCanvas.java
+++ b/java/src/com/tightvnc/rfbplayer/VncCanvas.java
@@ -180,48 +180,59 @@
   }
 
   void resizeDesktopFrame() {
+    // size the canvas
     setSize(rfb.framebufferWidth, rfb.framebufferHeight);
 
-    // FIXME: Find a better way to determine correct size of a
-    // ScrollPane.  -- const
-    Insets insets = player.desktopScrollPane.getInsets();
-    player.desktopScrollPane.setSize(rfb.framebufferWidth +
-                                     2 * Math.min(insets.left, insets.right),
-                                     rfb.framebufferHeight +
-                                     2 * Math.min(insets.top, insets.bottom));
-
-    player.vncFrame.pack();
-
-    // Try to limit the frame size to the screen size.
+    // determine screen size
     Dimension screenSize = player.vncFrame.getToolkit().getScreenSize();
-    Dimension frameSize = player.vncFrame.getSize();
-    Dimension newSize = frameSize;
+    Dimension scrollSize = player.desktopScrollPane.getSize();
 
     // Reduce Screen Size by 30 pixels in each direction;
     // This is a (poor) attempt to account for
     //     1) Menu bar on Macintosh (should really also account for
     //        Dock on OSX).  Usually 22px on top of screen.
-    //	   2) Taxkbar on Windows (usually about 28 px on bottom)
-    //	   3) Other obstructions.
-
+    //     2) Taxkbar on Windows (usually about 28 px on bottom)
+    //     3) Other obstructions.
     screenSize.height -= 30;
     screenSize.width -= 30;
 
+    // Further reduce the screen size to account for the
+    // scroll pane's insets.
+    Insets insets = player.desktopScrollPane.getInsets();
+    screenSize.height -= insets.top + insets.bottom;
+    screenSize.width -= insets.left + insets.right;
 
-    boolean needToResizeFrame = false;
-    if (frameSize.height > screenSize.height) {
-      newSize.height = screenSize.height;
-      needToResizeFrame = true;
+    // Limit pane size to fit on screen. 
+    boolean needResize = false;
+    if (scrollSize.width != rfb.framebufferWidth ||
+        scrollSize.height != rfb.framebufferHeight)
+      needResize = true;
+    int w = rfb.framebufferWidth, h = rfb.framebufferHeight;
+    if (w > screenSize.width) {
+      w = screenSize.width;
+      needResize = true;
     }
-    if (frameSize.width > screenSize.width) {
-      newSize.width = screenSize.width;
-      needToResizeFrame = true;
+    if (h > screenSize.height) {
+      h = screenSize.height;
+      needResize = true;
     }
-    if (needToResizeFrame) {
-      player.vncFrame.setSize(newSize);
-    }
+    if (needResize)
+      player.desktopScrollPane.setSize(w, h);
 
-    player.desktopScrollPane.doLayout();
+    player.vncFrame.pack();
+  }
+
+  void resizeEmbeddedApplet() {
+    // size the canvas
+    setSize(rfb.framebufferWidth, rfb.framebufferHeight);
+
+    // resize scroll pane if necessary
+    Dimension scrollSize = player.desktopScrollPane.getSize();
+    if (scrollSize.width != player.dispW ||
+        scrollSize.height != player.dispH)
+      player.desktopScrollPane.setSize(player.dispW, player.dispH);
+
+    player.validate();
   }
 
   //