Revision: 5149
          http://sourceforge.net/p/tigervnc/code/5149
Author:   bphinz
Date:     2014-01-02 01:23:56 +0000 (Thu, 02 Jan 2014)
Log Message:
-----------
Re-introduces embedded applet mode for the java viewer. On Windows and Linux, 
the embedded applet can be dragged from the browser window and detached from 
the browser process.  The mouse gesture for detaching the applet is ALT+drag on 
Windows and SHIFT+drag on Linux.

Modified Paths:
--------------
    trunk/java/com/tigervnc/vncviewer/CConn.java
    trunk/java/com/tigervnc/vncviewer/DesktopWindow.java
    trunk/java/com/tigervnc/vncviewer/F8Menu.java
    trunk/java/com/tigervnc/vncviewer/OptionsDialog.java
    trunk/java/com/tigervnc/vncviewer/README
    trunk/java/com/tigervnc/vncviewer/Viewport.java
    trunk/java/com/tigervnc/vncviewer/VncViewer.java
    trunk/java/com/tigervnc/vncviewer/index.vnc
    trunk/unix/xserver/hw/vnc/XserverDesktop.cc

Modified: trunk/java/com/tigervnc/vncviewer/CConn.java
===================================================================
--- trunk/java/com/tigervnc/vncviewer/CConn.java        2013-12-29 17:33:10 UTC 
(rev 5148)
+++ trunk/java/com/tigervnc/vncviewer/CConn.java        2014-01-02 01:23:56 UTC 
(rev 5149)
@@ -1,7 +1,7 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright 2009-2013 Pierre Ossman <oss...@cendio.se> for Cendio AB
  * Copyright (C) 2011-2013 D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2011-2013 Brian P. Hinz
+ * Copyright (C) 2011-2014 Brian P. Hinz
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,9 +56,9 @@
 import com.tigervnc.network.Socket;
 import com.tigervnc.network.TcpSocket;
 
-public class CConn extends CConnection
-  implements UserPasswdGetter, UserMsgBox, OptionsDialogCallback, 
FdInStreamBlockCallback
-{
+public class CConn extends CConnection implements 
+  UserPasswdGetter, UserMsgBox, OptionsDialogCallback, 
+  FdInStreamBlockCallback, ActionListener {
 
   public final PixelFormat getPreferredPF() { return fullColourPF; }
   static final PixelFormat verylowColourPF =
@@ -265,9 +265,58 @@
     cp.setPF(pendingPF);
     pendingPFChange = false;
 
-    recreateViewport();
+    if (viewer.embed.getValue()) {
+      desktop.setScaledSize();
+      setupEmbeddedFrame();
+    } else {
+      recreateViewport();
+    }
   }
 
+  void setupEmbeddedFrame() {
+    UIManager.getDefaults().put("ScrollPane.ancestorInputMap",
+      new UIDefaults.LazyInputMap(new Object[]{}));
+    JScrollPane sp = new JScrollPane();
+    sp.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
+    sp.getViewport().setBackground(Color.BLACK);
+    InputMap im = sp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
+    int ctrlAltShiftMask = Event.SHIFT_MASK | Event.CTRL_MASK | Event.ALT_MASK;
+    if (im != null) {
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, ctrlAltShiftMask),
+             "unitScrollUp");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, ctrlAltShiftMask),
+             "unitScrollDown");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, ctrlAltShiftMask),
+             "unitScrollLeft");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, ctrlAltShiftMask),
+             "unitScrollRight");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, ctrlAltShiftMask),
+             "scrollUp");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, ctrlAltShiftMask),
+             "scrollDown");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, ctrlAltShiftMask),
+             "scrollLeft");
+      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, ctrlAltShiftMask),
+             "scrollRight");
+    }
+    
sp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+    
sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
+    sp.getViewport().setView(desktop);
+    viewer.getContentPane().removeAll();
+    viewer.add(sp);
+    viewer.addFocusListener(new FocusAdapter() {
+      public void focusGained(FocusEvent e) {
+        if (desktop.isAncestorOf(viewer))
+          desktop.requestFocus();
+      }
+      public void focusLost(FocusEvent e) {
+        releaseModifiers();
+      }
+    });
+    viewer.validate();
+    desktop.requestFocus();
+  }
+
   // setDesktopSize() is called when the desktop size changes (including when
   // it is set initially).
   public void setDesktopSize(int w, int h) {
@@ -487,15 +536,28 @@
       return;
 
     desktop.resize();
-    recreateViewport();
+    if (viewer.embed.getValue()) {
+      desktop.setScaledSize();
+      setupEmbeddedFrame();
+    } else {
+      recreateViewport();
+    }
   }
+  
+  public void setEmbeddedFeatures(boolean s) {
+    menu.fullScreen.setEnabled(s);
+    menu.newConn.setEnabled(s);
+    options.fullScreen.setEnabled(s);
+    options.scalingFactor.setEnabled(s);
+  }
 
   // recreateViewport() recreates our top-level window.  This seems to be
   // better than attempting to resize the existing window, at least with
   // various X window managers.
 
-  private void recreateViewport()
-  {
+  public void recreateViewport() {
+    if (viewer.embed.getValue())
+      return;
     if (viewport != null) viewport.dispose();
     viewport = new Viewport(cp.name(), this);
     viewport.setUndecorated(fullScreen);
@@ -506,8 +568,7 @@
     desktop.requestFocusInWindow();
   }
 
-  private void reconfigureViewport()
-  {
+  private void reconfigureViewport() {
     //viewport.setMaxSize(cp.width, cp.height);
     boolean pack = true;
     Dimension dpySize = viewport.getToolkit().getScreenSize();
@@ -680,6 +741,14 @@
 
   // close() shuts down the socket, thus waking up the RFB thread.
   public void close() {
+    if (closeListener != null) {
+      viewer.embed.setParam(true);
+      if (VncViewer.nViewers == 1) {
+        JFrame f = (JFrame)JOptionPane.getFrameForComponent(viewer);
+        if (f != null)
+          f.dispatchEvent(new WindowEvent(f, WindowEvent.WINDOW_CLOSING));
+      }
+    }
     deleteWindow();
     shuttingDown = true;
     try {
@@ -723,7 +792,7 @@
     JOptionPane op =
       new JOptionPane(msg, JOptionPane.INFORMATION_MESSAGE,
                       JOptionPane.DEFAULT_OPTION, VncViewer.logoIcon);
-    JDialog dlg = op.createDialog("About TigerVNC Viewer for Java");
+    JDialog dlg = op.createDialog(desktop, "About TigerVNC Viewer for Java");
     dlg.setIconImage(VncViewer.frameIcon);
     dlg.setVisible(true);
     if (fullScreenWindow != null)
@@ -758,7 +827,7 @@
                     csecurity.description());
     JOptionPane op = new JOptionPane(msg, JOptionPane.PLAIN_MESSAGE,
                                      JOptionPane.DEFAULT_OPTION);
-    JDialog dlg = op.createDialog("VNC connection info");
+    JDialog dlg = op.createDialog(desktop, "VNC connection info");
     dlg.setIconImage(VncViewer.frameIcon);
     dlg.setVisible(true);
     if (fullScreenWindow != null)
@@ -1134,6 +1203,8 @@
   }
 
   public void toggleFullScreen() {
+    if (viewer.embed.getValue())
+      return;
     fullScreen = !fullScreen;
     menu.fullScreen.setSelected(fullScreen);
     if (viewport != null) {
@@ -1319,7 +1390,14 @@
       writeKeyEvent(Keysyms.Super_R, true);
   }
 
+  // this is a special ActionListener passed in by the
+  // Java Plug-in software to control applet's close behavior
+  public void setCloseListener(ActionListener cl) {
+    closeListener = cl;
+  }
 
+  public void actionPerformed(ActionEvent e) {}
+
   ////////////////////////////////////////////////////////////////////
   // The following methods are called from both RFB and GUI threads
 
@@ -1401,6 +1479,7 @@
   private boolean autoSelect;
   boolean fullScreen;
   private HashMap<Integer, Integer> downKeySym;
+  public ActionListener closeListener = null;
 
   static LogWriter vlog = new LogWriter("CConn");
 }

Modified: trunk/java/com/tigervnc/vncviewer/DesktopWindow.java
===================================================================
--- trunk/java/com/tigervnc/vncviewer/DesktopWindow.java        2013-12-29 
17:33:10 UTC (rev 5148)
+++ trunk/java/com/tigervnc/vncviewer/DesktopWindow.java        2014-01-02 
01:23:56 UTC (rev 5149)
@@ -2,7 +2,7 @@
  * Copyright (C) 2006 Constantin Kaplinsky.  All Rights Reserved.
  * Copyright (C) 2009 Paul Donohue.  All Rights Reserved.
  * Copyright (C) 2010, 2012-2013 D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2011-2013 Brian P. Hinz
+ * Copyright (C) 2011-2014 Brian P. Hinz
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -426,7 +426,10 @@
   public void mouseReleased(MouseEvent e) { mouseCB(e); }
   public void mousePressed(MouseEvent e) { mouseCB(e); }
   public void mouseClicked(MouseEvent e) {}
-  public void mouseEntered(MouseEvent e) {}
+  public void mouseEntered(MouseEvent e) {
+    if (cc.viewer.embed.getValue())
+      requestFocus();
+  }
   public void mouseExited(MouseEvent e) {}
 
   // MouseWheel callback function

Modified: trunk/java/com/tigervnc/vncviewer/F8Menu.java
===================================================================
--- trunk/java/com/tigervnc/vncviewer/F8Menu.java       2013-12-29 17:33:10 UTC 
(rev 5148)
+++ trunk/java/com/tigervnc/vncviewer/F8Menu.java       2014-01-02 01:23:56 UTC 
(rev 5149)
@@ -1,5 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * Copyright (C) 2011 Brian P. Hinz
+ * Copyright (C) 2011-2014 Brian P. Hinz
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -49,6 +49,7 @@
     fullScreen.setMnemonic(KeyEvent.VK_F);
     fullScreen.setSelected(cc.fullScreen);
     fullScreen.addActionListener(this);
+    fullScreen.setEnabled(!cc.viewer.embed.getValue());
     add(fullScreen);
     addSeparator();
     clipboard  = addMenuItem("Clipboard...");
@@ -59,6 +60,7 @@
     refresh    = addMenuItem("Refresh Screen", KeyEvent.VK_H);
     addSeparator();
     newConn    = addMenuItem("New connection...", KeyEvent.VK_W);
+    newConn.setEnabled(!cc.viewer.embed.getValue());
     options    = addMenuItem("Options...", KeyEvent.VK_O);
     save       = addMenuItem("Save connection info as...", KeyEvent.VK_S);
     info       = addMenuItem("Connection info...", KeyEvent.VK_I);

Modified: trunk/java/com/tigervnc/vncviewer/OptionsDialog.java
===================================================================
--- trunk/java/com/tigervnc/vncviewer/OptionsDialog.java        2013-12-29 
17:33:10 UTC (rev 5148)
+++ trunk/java/com/tigervnc/vncviewer/OptionsDialog.java        2014-01-02 
01:23:56 UTC (rev 5149)
@@ -1,5 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * Copyright (C) 2011-2012 Brian P. Hinz
+ * Copyright (C) 2011-2014 Brian P. Hinz
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,7 +36,7 @@
   // Static variables
   static LogWriter vlog = new LogWriter("OptionsDialog");
 
-  OptionsDialogCallback cb;
+  CConn cc;
   JPanel FormatPanel, InputsPanel, MiscPanel, DefaultsPanel, SecPanel;
   JCheckBox autoSelect, customCompressLevel, noJpeg;
   @SuppressWarnings({"rawtypes"})
@@ -53,9 +53,9 @@
   JButton cfLoadButton, cfSaveAsButton, defSaveButton, defReloadButton, 
defClearButton;
 
   @SuppressWarnings({"rawtypes","unchecked"})
-  public OptionsDialog(OptionsDialogCallback cb_) {
+  public OptionsDialog(CConn cc_) {
     super(true);
-    cb = cb_;
+    cc = cc_;
     setResizable(false);
     setTitle("VNC Viewer Options");
 
@@ -149,6 +149,7 @@
 
     fullScreen = new JCheckBox("Full-screen mode");
     fullScreen.addItemListener(this);
+    fullScreen.setEnabled(!cc.viewer.embed.getValue());
     shared = new JCheckBox("Shared connection (do not disconnect other 
viewers)");
     shared.addItemListener(this);
     useLocalCursor = new JCheckBox("Render cursor locally");
@@ -172,6 +173,7 @@
     }
     scalingFactor.setEditable(true);
     scalingFactor.addItemListener(this);
+    scalingFactor.setEnabled(!cc.viewer.embed.getValue());
     addGBComponent(fullScreen,MiscPanel,     0, 0, 2, 1, 2, 2, 1, 0, 
GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new 
Insets(4,5,0,5));
     addGBComponent(shared,MiscPanel,         0, 1, 2, 1, 2, 2, 1, 0, 
GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new 
Insets(4,5,0,5));
     addGBComponent(useLocalCursor,MiscPanel, 0, 2, 2, 1, 2, 2, 1, 0, 
GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new 
Insets(4,5,0,5));
@@ -205,7 +207,6 @@
 
     addGBComponent(configPanel,DefaultsPanel, 0, 0, 1, 
GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, 
GridBagConstraints.PAGE_START, new Insets(4,5,4,5));
     addGBComponent(defaultsPanel,DefaultsPanel, 1, 0, 1, 
GridBagConstraints.REMAINDER, 0, 0, 1, 1, GridBagConstraints.HORIZONTAL, 
GridBagConstraints.PAGE_START, new Insets(4,0,4,5));
-    //defReloadButton.setEnabled(!applet);
 
     // security tab
     SecPanel=new JPanel(new GridBagLayout());
@@ -278,7 +279,7 @@
   }
 
   public void initDialog() {
-    if (cb != null) cb.setOptions();
+    if (cc != null) cc.setOptions();
     zrle.setEnabled(!autoSelect.isSelected());
     hextile.setEnabled(!autoSelect.isSelected());
     tight.setEnabled(!autoSelect.isSelected());
@@ -472,7 +473,6 @@
 
   public void endDialog() {
     super.endDialog();
-    CConn cc = (CConn)cb;
     if (cc.viewport != null && cc.viewport.isVisible()) {
       cc.viewport.toFront();
       cc.viewport.requestFocus();
@@ -482,7 +482,7 @@
   public void actionPerformed(ActionEvent e) {
     Object s = e.getSource();
     if (s instanceof JButton && (JButton)s == okButton) {
-      if (cb != null) cb.getOptions();
+      if (cc != null) cc.getOptions();
       endDialog();
     } else if (s instanceof JButton && (JButton)s == cancelButton) {
       endDialog();
@@ -496,7 +496,7 @@
         String filename = fc.getSelectedFile().toString();
         if (filename != null)
           Configuration.load(filename);
-        cb.setOptions();
+        cc.setOptions();
       }
     } else if (s instanceof JButton && (JButton)s == cfSaveAsButton) {
       JFileChooser fc = new JFileChooser();
@@ -516,7 +516,7 @@
       restorePreferences();
     } else if (s instanceof JButton && (JButton)s == defClearButton) {
       UserPreferences.clear();
-      cb.setOptions();
+      cc.setOptions();
     } else if (s instanceof JButton && (JButton)s == ca) {
       JFileChooser fc = new JFileChooser(new 
File(CSecurityTLS.getDefaultCA()));
       fc.setDialogTitle("Path to X509 CA certificate");

Modified: trunk/java/com/tigervnc/vncviewer/README
===================================================================
--- trunk/java/com/tigervnc/vncviewer/README    2013-12-29 17:33:10 UTC (rev 
5148)
+++ trunk/java/com/tigervnc/vncviewer/README    2014-01-02 01:23:56 UTC (rev 
5149)
@@ -13,6 +13,7 @@
         Copyright (C) 2005 Martin Koegler
         Copyright (C) 2009 Pierre Ossman for Cendio AB
         Copyright (C) 2009-2013 TigerVNC Team
+        Copyright (C) 2011-2014 Brian P. Hinz
         All rights reserved.
 
 This software is distributed under the GNU General Public Licence as
@@ -46,6 +47,10 @@
      Java Viewer by simply copying a new version of VncViewer.jar and/or
      index.vnc into the VNC classes directory.
 
+     On Windows and Linux, the embedded applet can be drag-undocked from the 
+     browser window and converted to a standalone application. The drag
+     gesture ALT+drag on Windows, and SHIFT+drag on Linux.
+
      In the case of the Windows TigerVNC Server, VncViewer.jar and index.vnc
      are embedded as resources in the WinVNC executable, so deploying a
      modified version of the TigerVNC Java Viewer on a Windows server requires

Modified: trunk/java/com/tigervnc/vncviewer/Viewport.java
===================================================================
--- trunk/java/com/tigervnc/vncviewer/Viewport.java     2013-12-29 17:33:10 UTC 
(rev 5148)
+++ trunk/java/com/tigervnc/vncviewer/Viewport.java     2014-01-02 01:23:56 UTC 
(rev 5149)
@@ -1,5 +1,5 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * Copyright (C) 2011-2013 Brian P. Hinz
+ * Copyright (C) 2011-2014 Brian P. Hinz
  * Copyright (C) 2012-2013 D. R. Commander.  All Rights Reserved.
  *
  * This is free software; you can redistribute it and/or modify
@@ -64,7 +64,11 @@
     addWindowListener(new WindowAdapter() {
       public void windowClosing(WindowEvent e) {
         if (VncViewer.nViewers == 1) {
-          cc.viewer.exit(1);
+          if (cc.closeListener != null) {
+            cc.close();
+          } else {
+            cc.viewer.exit(1);
+          }
         } else {
           cc.close();
         }
@@ -163,19 +167,19 @@
   }
 
   public static Window getFullScreenWindow() {
-      GraphicsEnvironment ge =
-        GraphicsEnvironment.getLocalGraphicsEnvironment();
-      GraphicsDevice gd = ge.getDefaultScreenDevice();
-      Window fullScreenWindow = gd.getFullScreenWindow();
-      return fullScreenWindow;
+    GraphicsEnvironment ge =
+      GraphicsEnvironment.getLocalGraphicsEnvironment();
+    GraphicsDevice gd = ge.getDefaultScreenDevice();
+    Window fullScreenWindow = gd.getFullScreenWindow();
+    return fullScreenWindow;
   }
 
   public static void setFullScreenWindow(Window fullScreenWindow) {
-      GraphicsEnvironment ge =
-        GraphicsEnvironment.getLocalGraphicsEnvironment();
-      GraphicsDevice gd = ge.getDefaultScreenDevice();
-      if (gd.isFullScreenSupported())
-        gd.setFullScreenWindow(fullScreenWindow);
+    GraphicsEnvironment ge =
+      GraphicsEnvironment.getLocalGraphicsEnvironment();
+    GraphicsDevice gd = ge.getDefaultScreenDevice();
+    if (gd.isFullScreenSupported())
+      gd.setFullScreenWindow(fullScreenWindow);
   }
 
   CConn cc;

Modified: trunk/java/com/tigervnc/vncviewer/VncViewer.java
===================================================================
--- trunk/java/com/tigervnc/vncviewer/VncViewer.java    2013-12-29 17:33:10 UTC 
(rev 5148)
+++ trunk/java/com/tigervnc/vncviewer/VncViewer.java    2014-01-02 01:23:56 UTC 
(rev 5149)
@@ -1,7 +1,7 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright 2011 Pierre Ossman <oss...@cendio.se> for Cendio AB
  * Copyright (C) 2011-2013 D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2011-2013 Brian P. Hinz
+ * Copyright (C) 2011-2014 Brian P. Hinz
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@
 package com.tigervnc.vncviewer;
 
 import java.awt.*;
+import java.awt.event.*;
 import java.awt.Color;
 import java.awt.Graphics;
 import java.awt.Image;
@@ -49,8 +50,9 @@
 import com.tigervnc.rfb.*;
 import com.tigervnc.network.*;
 
-public class VncViewer extends java.applet.Applet implements Runnable
-{
+public class VncViewer extends javax.swing.JApplet 
+  implements Runnable, ActionListener {
+
   public static final String aboutText = new String("TigerVNC Java Viewer v%s 
(%s)%n"+
                                                     "Built on %s at %s%n"+
                                                     "Copyright (C) 1999-2013 
TigerVNC Team and many others (see README.txt)%n"+
@@ -122,7 +124,7 @@
 
 
   public VncViewer(String[] argv) {
-    applet = false;
+    embed.setParam(false);
 
     // load user preferences
     UserPreferences.load("global");
@@ -268,12 +270,12 @@
 
   public VncViewer() {
     UserPreferences.load("global");
-    applet = true;
+    embed.setParam(true);
   }
 
   public static void newViewer(VncViewer oldViewer, Socket sock, boolean 
close) {
     VncViewer viewer = new VncViewer();
-    viewer.applet = oldViewer.applet;
+    viewer.embed.setParam(oldViewer.embed.getValue());
     viewer.sock = sock;
     viewer.start();
     if (close)
@@ -288,8 +290,56 @@
     newViewer(oldViewer, null);
   }
 
+  public boolean isAppletDragStart(MouseEvent e) {
+    if(e.getID() == MouseEvent.MOUSE_DRAGGED) {
+      // Drag undocking on Mac works, but introduces a host of
+      // problems so disable it for now.
+      if (os.startsWith("mac os x"))
+        return false;
+      else if (os.startsWith("windows"))
+        return (e.getModifiersEx() & MouseEvent.ALT_DOWN_MASK) != 0;
+      else
+        return (e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) != 0;
+    } else {
+      return false;
+    }
+  }
+
+  public void appletDragStarted() {
+    embed.setParam(false);
+    cc.recreateViewport();
+    JFrame f = (JFrame)JOptionPane.getFrameForComponent(this);
+    // The default JFrame created by the drag event will be
+    // visible briefly between appletDragStarted and Finished.
+    if (f != null)
+      f.setSize(0, 0);
+  }
+
+  public void appletDragFinished() {
+    cc.setEmbeddedFeatures(true);
+    JFrame f = (JFrame)JOptionPane.getFrameForComponent(this);
+    if (f != null)
+      f.dispose();
+  }
+
+  public void setAppletCloseListener(ActionListener cl) {
+    cc.setCloseListener(cl);
+  }
+
+  public void appletRestored() {
+    cc.setEmbeddedFeatures(false);
+    cc.setCloseListener(null);
+  }
+
   public void init() {
     vlog.debug("init called");
+    Container parent = getParent();
+    while (!parent.isFocusCycleRoot()) {
+      parent = parent.getParent();
+    }
+    ((Frame)parent).setModalExclusionType(null);
+    parent.setFocusable(false);
+    parent.setFocusTraversalKeysEnabled(false);
     setLookAndFeel();
     setBackground(Color.white);
   }
@@ -310,9 +360,11 @@
   public void start() {
     vlog.debug("start called");
     getTimestamp();
-    if (applet && nViewers == 0) {
+    if (embed.getValue() && nViewers == 0) {
       alwaysShowServerDialog.setParam(true);
       Configuration.global().readAppletParams(this);
+      fullScreen.setParam(false);
+      scalingFactor.setParam("100");
       String host = getCodeBase().getHost();
       if (vncServerName.getValue() == null && vncServerPort.getValue() != 0) {
         int port = vncServerPort.getValue();
@@ -330,22 +382,48 @@
     nViewers--;
     if (nViewers > 0)
       return;
-    if (applet) {
+    if (embed.getValue())
       destroy();
-    } else {
+    else
       System.exit(n);
-    }
   }
 
-  public void paint(Graphics g) {
-    g.drawImage(logoImage, 0, 0, this);
-    int h = logoImage.getHeight(this)+20;
-    g.drawString(String.format(aboutText, version, build,
-                               buildDate, buildTime), 0, h);
+  // If "Reconnect" button is pressed
+  public void actionPerformed(ActionEvent e) {
+    getContentPane().removeAll();
+    start();
   }
 
+  void reportException(java.lang.Exception e) {
+    String title, msg = e.getMessage();
+    int msgType = JOptionPane.ERROR_MESSAGE;
+    title = "TigerVNC Viewer : Error";
+    e.printStackTrace();
+    if (embed.getValue()) {
+      getContentPane().removeAll();
+      JLabel label = new JLabel("<html><center><b>" + title + "</b><p><i>" +
+                                msg + "</i></center></html>", JLabel.CENTER);
+      label.setFont(new Font("Helvetica", Font.PLAIN, 24));
+      label.setMaximumSize(new Dimension(getSize().width, 100));
+      label.setVerticalAlignment(JLabel.CENTER);
+      label.setAlignmentX(Component.CENTER_ALIGNMENT);
+      JButton button = new JButton("Reconnect");
+      button.addActionListener(this);
+      button.setMaximumSize(new Dimension(200, 30));
+      button.setAlignmentX(Component.CENTER_ALIGNMENT);
+      setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
+      add(label);
+      add(button);
+      validate();
+      repaint();
+    } else {
+      JOptionPane.showMessageDialog(null, msg, title, msgType);
+    }
+  }
+
+  CConn cc;
   public void run() {
-    CConn cc = null;
+    cc = null;
 
     if (listenMode.getValue()) {
       int port = 5500;
@@ -358,7 +436,7 @@
       try {
         listener = new TcpListener(null, port);
       } catch (java.lang.Exception e) {
-        System.out.println(e.toString());
+        reportException(e);
         exit(1);
       }
 
@@ -376,18 +454,14 @@
       while (!cc.shuttingDown)
         cc.processMsg();
     } catch (java.lang.Exception e) {
-      if (e instanceof EndOfStream) {
-        vlog.info(e.getMessage());
-      } else if (cc == null || !cc.shuttingDown) {
-        e.printStackTrace();
-        JOptionPane op =
-          new JOptionPane(e.getMessage(), JOptionPane.WARNING_MESSAGE);
-        JDialog dlg = op.createDialog("TigerVNC Viewer");
-        dlg.setIconImage(frameIcon);
-        dlg.setVisible(true);
+      if (cc == null || !cc.shuttingDown) {
+        reportException(e);
+        if (cc != null)
+          cc.deleteWindow();
+        exit(1);
+      } else if (embed.getValue()) {
+        reportException(new java.lang.Exception("Connection closed"));
       } else {
-        if (!cc.shuttingDown)
-          vlog.info(e.toString());
         cc = null;
       }
     }
@@ -400,6 +474,13 @@
   static BoolParameter noLionFS
   = new BoolParameter("NoLionFS", null, false);
 
+  BoolParameter embed
+  = new BoolParameter("Embed",
+  "If the viewer is being run as an applet, display its output to " +
+  "an embedded frame in the browser window rather than to a dedicated " +
+  "window.  This also has the effect of setting FullScreen=0, and Scale=100.",
+  false);
+
   BoolParameter useLocalCursor
   = new BoolParameter("UseLocalCursor",
                       "Render the mouse cursor locally",
@@ -568,7 +649,6 @@
 
   Thread thread;
   Socket sock;
-  boolean applet;
   static int nViewers;
   static LogWriter vlog = new LogWriter("main");
 }

Modified: trunk/java/com/tigervnc/vncviewer/index.vnc
===================================================================
--- trunk/java/com/tigervnc/vncviewer/index.vnc 2013-12-29 17:33:10 UTC (rev 
5148)
+++ trunk/java/com/tigervnc/vncviewer/index.vnc 2014-01-02 01:23:56 UTC (rev 
5149)
@@ -14,6 +14,8 @@
 <APPLET CODE=com.tigervnc.vncviewer.VncViewer ARCHIVE=VncViewer.jar
         WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
 <param name=PORT value=$PORT>
+<param name="Embed" value="true">
+<param name="draggable" value="true">
 </APPLET>
 <BR>
 <A href="http://www.tigervnc.org/";>TigerVNC site</A>

Modified: trunk/unix/xserver/hw/vnc/XserverDesktop.cc
===================================================================
--- trunk/unix/xserver/hw/vnc/XserverDesktop.cc 2013-12-29 17:33:10 UTC (rev 
5148)
+++ trunk/unix/xserver/hw/vnc/XserverDesktop.cc 2014-01-02 01:23:56 UTC (rev 
5149)
@@ -1,5 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright 2009-2011 Pierre Ossman for Cendio AB
+ * Copyright 2014 Brian P. Hinz
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -338,7 +339,7 @@
   }
   if (strcmp(varName, "$APPLETHEIGHT") == 0) {
     char* str = new char[10];
-    sprintf(str, "%d", height() + 32);
+    sprintf(str, "%d", height());
     return str;
   }
   if (strcmp(varName, "$DESKTOP") == 0) {

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
Tigervnc-commits mailing list
Tigervnc-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tigervnc-commits

Reply via email to