Copied Lion fullScreen code from TurboVNC viewer.  This is a more robust implementation and does not suffer from Java bugs 8009911 or 4783448 like the existing code did. CMakeLists file was also updated to be more similar to the TurboVNC cmake file.  This wasn't strictly necessary but it simplifies things a bit.

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@5142 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt
index 05d77e4..c640da8 100644
--- a/java/CMakeLists.txt
+++ b/java/CMakeLists.txt
@@ -7,14 +7,14 @@
 
 find_package(Java)
 
-set(DEFAULT_JAVACFLAGS "-source 1.5 -target 1.5 -Xlint:all,-serial,-cast,-fallthrough,-dep-ann,-deprecation")
+set(DEFAULT_JAVACFLAGS "-source 1.5 -target 1.5 -Xlint:all,-serial,-cast,-unchecked,-fallthrough,-dep-ann,-deprecation,-rawtypes")
 set(JAVACFLAGS ${DEFAULT_JAVACFLAGS} CACHE STRING
   "Java compiler flags (Default: ${DEFAULT_JAVACFLAGS})")
 message(STATUS "Java compiler flags = ${JAVACFLAGS}")
 
 set(CLASSPATH com/tigervnc/vncviewer)
-set(JAVA_SRCDIR ${CMAKE_CURRENT_SOURCE_DIR}/${CLASSPATH})
-set(JAVA_BINDIR ${CMAKE_CURRENT_BINARY_DIR}/${CLASSPATH})
+set(SRCDIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(BINDIR ${CMAKE_CURRENT_BINARY_DIR})
 
 if(NOT BUILD)
 	execute_process(COMMAND "date" "+%Y%m%d" OUTPUT_VARIABLE BUILD)
@@ -25,26 +25,8 @@
 string(REGEX REPLACE "\n" "" JAVA_TIME ${JAVA_TIME})
 string(REGEX REPLACE "\n" "" BUILD ${BUILD})
 
-set(JAVA_CLASSNAMES
-  CConn
-  ClipboardDialog
-  DesktopWindow
-  Dialog
-  F8Menu
-  OptionsDialogCallback
-  PasswdDialog
-  PlatformPixelBuffer
-  OptionsDialog
-  ServerDialog
-  VncViewer)
-
 set(JAVA_SOURCES "")
-set(JAVA_CLASSES_FULL "")
-foreach(class ${JAVA_CLASSNAMES})
-  set(JAVA_SOURCES ${JAVA_SOURCES} ${JAVA_SRCDIR}/${class}.java)
-  set(JAVA_CLASSES_FULL ${JAVA_CLASSES_FULL}
-    ${CMAKE_CURRENT_BINARY_DIR}/${CLASSPATH}/${class}.class)
-endforeach()
+set(JAVA_CLASSES "")
 
 set(JSCH_CLASSNAMES
   DH
@@ -88,55 +70,61 @@
   jcraft/HMACMD5
   jcraft/HMACSHA196
   jcraft/HMACSHA1)
-set(JSCH_SRCDIR ${CMAKE_CURRENT_SOURCE_DIR}/com/jcraft/jsch)
+
 foreach(class ${JSCH_CLASSNAMES})
-  set(JAVA_SOURCES ${JAVA_SOURCES} ${JSCH_SRCDIR}/${class}.java)
-  set(JAVA_CLASSES_FULL ${JAVA_CLASSES_FULL}
-    ${CMAKE_CURRENT_BINARY_DIR}/com/jcraft/jsch/${class}.class)
+  set(JAVA_SOURCES ${JAVA_SOURCES} com/jcraft/jsch/${class}.java)
+  set(JAVA_CLASSES ${JAVA_CLASSES}
+    ${BINDIR}/com/jcraft/jsch/${class}.class)
 endforeach()
 
 file(GLOB DEPEND_SOURCES
-  ${CMAKE_CURRENT_SOURCE_DIR}/com/tigervnc/rfb/*.java
-  ${CMAKE_CURRENT_SOURCE_DIR}/com/tigervnc/rdr/*.java
-  ${CMAKE_CURRENT_SOURCE_DIR}/com/tigervnc/network/*.java
-  ${CMAKE_CURRENT_SOURCE_DIR}/com/jcraft/jsch/*.java
-  ${CMAKE_CURRENT_SOURCE_DIR}/com/jcraft/jsch/jcraft/*.java
-  ${CMAKE_CURRENT_SOURCE_DIR}/com/jcraft/jsch/jgss/*.java
-  ${CMAKE_CURRENT_SOURCE_DIR}/com/jcraft/jzlib/*.java)
+  ${SRCDIR}/${CLASSPATH}/*.java
+  ${SRCDIR}/com/tigervnc/rfb/*.java
+  ${SRCDIR}/com/tigervnc/rdr/*.java
+  ${SRCDIR}/com/tigervnc/network/*.java
+  ${SRCDIR}/com/jcraft/jsch/*.java
+  ${SRCDIR}/com/jcraft/jsch/jcraft/*.java
+  ${SRCDIR}/com/jcraft/jsch/jgss/*.java
+  ${SRCDIR}/com/jcraft/jzlib/*.java)
 
 string(REGEX REPLACE " " ";" JAVACFLAGS "${JAVACFLAGS}")
-add_custom_command(OUTPUT ${JAVA_CLASSES_FULL}
+add_custom_command(OUTPUT ${JAVA_CLASSES}
   DEPENDS ${JAVA_SOURCES} ${DEPEND_SOURCES}
   COMMAND ${JAVA_COMPILE}
-  ARGS ${JAVACFLAGS} -sourcepath ${CMAKE_CURRENT_SOURCE_DIR}
-    -d ${CMAKE_CURRENT_BINARY_DIR} ${JAVA_SOURCES})
+  ARGS ${JAVACFLAGS} -sourcepath ${SRCDIR} -d ${BINDIR} 
+    ${CLASSPATH}/VncViewer.java ${JAVA_SOURCES}
+	WORKING_DIRECTORY ${SRCDIR})
 
 configure_file(${CLASSPATH}/timestamp.in ${CLASSPATH}/timestamp)
 
-add_custom_command(OUTPUT ${JAVA_BINDIR}/tigervnc.png
-  COMMAND ${CMAKE_COMMAND} -E copy_if_different
-    ${JAVA_SRCDIR}/tigervnc.png ${JAVA_BINDIR}/tigervnc.png
-  DEPENDS ${JAVA_SRCDIR}/tigervnc.png)
+if(NOT "${SRCDIR}" STREQUAL "${BINDIR}")
 
-add_custom_command(OUTPUT ${JAVA_BINDIR}/tigervnc.ico
+add_custom_command(OUTPUT ${BINDIR}/${CLASSPATH}/tigervnc.png
   COMMAND ${CMAKE_COMMAND} -E copy_if_different
-    ${JAVA_SRCDIR}/tigervnc.ico ${JAVA_BINDIR}/tigervnc.ico
-  DEPENDS ${JAVA_SRCDIR}/tigervnc.ico)
+    ${SRCDIR}/${CLASSPATH}/tigervnc.png ${BINDIR}/${CLASSPATH}/tigervnc.png
+  DEPENDS ${SRCDIR}/${CLASSPATH}/tigervnc.png)
+
+add_custom_command(OUTPUT ${BINDIR}/${CLASSPATH}/tigervnc.ico
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different
+    ${SRCDIR}/${CLASSPATH}/tigervnc.ico ${BINDIR}/${CLASSPATH}/tigervnc.ico
+  DEPENDS ${SRCDIR}/${CLASSPATH}/tigervnc.ico)
+
+endif()
 
 string(REGEX REPLACE "jar" "" Java_PATH ${Java_JAR_EXECUTABLE})
 string(REGEX REPLACE ".exe" "" Java_PATH ${Java_PATH})
 
 add_custom_command(OUTPUT VncViewer.jar
-  DEPENDS ${JAVA_CLASSES_FULL}
-    ${JAVA_SRCDIR}/MANIFEST.MF
-    ${JAVA_BINDIR}/timestamp
-    ${JAVA_BINDIR}/tigervnc.png
-    ${JAVA_BINDIR}/tigervnc.ico
+  DEPENDS ${JAVA_CLASSES}
+    ${SRCDIR}/${CLASSPATH}/MANIFEST.MF
+    ${BINDIR}/${CLASSPATH}/timestamp
+    ${BINDIR}/${CLASSPATH}/tigervnc.png
+    ${BINDIR}/${CLASSPATH}/tigervnc.ico
   COMMAND ${JAVA_ARCHIVE}
   ARGS cfm VncViewer.jar
-    ${JAVA_SRCDIR}/MANIFEST.MF
-    com/tigervnc/vncviewer/timestamp
-    com/tigervnc/vncviewer/*.class
+    ${SRCDIR}/${CLASSPATH}/MANIFEST.MF
+    ${CLASSPATH}/timestamp
+    ${CLASSPATH}/*.class
     com/tigervnc/rfb/*.class
     com/tigervnc/rdr/*.class
     com/tigervnc/network/*.class
@@ -147,17 +135,16 @@
     com/tigervnc/vncviewer/tigervnc.png
     com/tigervnc/vncviewer/tigervnc.ico
   COMMAND ${CMAKE_COMMAND}
-  ARGS -DJava_PATH=${Java_PATH}
-    -DJAR_FILE=${CMAKE_CURRENT_BINARY_DIR}/VncViewer.jar
-    -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/SignJar.cmake)
+  ARGS -DJava_PATH=${Java_PATH} -DJAR_FILE=${BINDIR}/VncViewer.jar
+    -P ${SRCDIR}/cmake/SignJar.cmake)
 
 add_custom_target(java ALL DEPENDS VncViewer.jar)
 
 if(NOT WIN32)
   install(FILES
     ${CMAKE_CURRENT_BINARY_DIR}/VncViewer.jar
-    ${JAVA_SRCDIR}/README
-    ${JAVA_SRCDIR}/index.vnc
-    ${JAVA_SRCDIR}/favicon.ico
+    ${SRCDIR}/README
+    ${SRCDIR}/index.vnc
+    ${SRCDIR}/favicon.ico
     DESTINATION ${DATA_DIR}/vnc/classes)
 endif()
diff --git a/java/com/tigervnc/vncviewer/CConn.java b/java/com/tigervnc/vncviewer/CConn.java
index 15521aa..805d832 100644
--- a/java/com/tigervnc/vncviewer/CConn.java
+++ b/java/com/tigervnc/vncviewer/CConn.java
@@ -513,14 +513,10 @@
     desktop.setScaledSize();
     int w = desktop.scaledWidth;
     int h = desktop.scaledHeight;
-    GraphicsEnvironment ge =
-      GraphicsEnvironment.getLocalGraphicsEnvironment();
-    GraphicsDevice gd = ge.getDefaultScreenDevice();
     if (fullScreen) {
       viewport.setExtendedState(JFrame.MAXIMIZED_BOTH);
       viewport.setGeometry(0, 0, dpySize.width, dpySize.height, false);
-      if (gd.isFullScreenSupported())
-        gd.setFullScreenWindow(viewport);
+      Viewport.setFullScreenWindow(viewport);
     } else {
       int wmDecorationWidth = viewport.getInsets().left + viewport.getInsets().right;
       int wmDecorationHeight = viewport.getInsets().top + viewport.getInsets().bottom;
@@ -545,8 +541,7 @@
         viewport.setExtendedState(JFrame.NORMAL);
         viewport.setGeometry(x, y, w, h, pack);
       }
-      if (gd.isFullScreenSupported())
-        gd.setFullScreenWindow(null);
+      Viewport.setFullScreenWindow(null);
     }
   }
 
@@ -1140,8 +1135,13 @@
   public void toggleFullScreen() {
     fullScreen = !fullScreen;
     menu.fullScreen.setSelected(fullScreen);
-    if (viewport != null)
-      recreateViewport();
+    if (viewport != null) {
+      if (!viewport.lionFSSupported()) {
+        recreateViewport();
+      } else {
+        viewport.toggleLionFS();
+      }
+    }
   }
 
   // writeClientCutText() is called from the clipboard dialog
diff --git a/java/com/tigervnc/vncviewer/Viewport.java b/java/com/tigervnc/vncviewer/Viewport.java
index 66ac131..f43f592 100644
--- a/java/com/tigervnc/vncviewer/Viewport.java
+++ b/java/com/tigervnc/vncviewer/Viewport.java
@@ -1,6 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright (C) 2011-2013 Brian P. Hinz
- * Copyright (C) 2012 D. R. Commander.  All Rights Reserved.
+ * Copyright (C) 2012-2013 D. R. Commander.  All Rights Reserved.
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,10 +28,11 @@
 import java.awt.GraphicsDevice;
 import java.awt.GraphicsEnvironment;
 import java.awt.Window;
+import java.lang.reflect.*;
 import javax.swing.*;
 
-import com.tigervnc.rdr.*;
 import com.tigervnc.rfb.*;
+import java.lang.Exception;
 
 public class Viewport extends JFrame
 {
@@ -47,6 +48,10 @@
     sp.getViewport().setBackground(Color.BLACK);
     sp.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
     getContentPane().add(sp);
+    if (VncViewer.os.startsWith("mac os x")) {
+      if (!VncViewer.noLionFS.getValue())
+        enableLionFS();
+    }
     addWindowFocusListener(new WindowAdapter() {
       public void windowGainedFocus(WindowEvent e) {
         if (isVisible())
@@ -100,6 +105,49 @@
     });
   }
 
+  boolean lionFSSupported() { return canDoLionFS; }
+
+  void enableLionFS() {
+    try {
+      String version = System.getProperty("os.version");
+      int firstDot = version.indexOf('.');
+      int lastDot = version.lastIndexOf('.');
+      if (lastDot > firstDot && lastDot >= 0) {
+        version = version.substring(0, version.indexOf('.', firstDot + 1));
+      }
+      double v = Double.parseDouble(version);
+      if (v < 10.7)
+        throw new Exception("Operating system version is " + v);
+
+      Class fsuClass = Class.forName("com.apple.eawt.FullScreenUtilities");
+      Class argClasses[] = new Class[]{Window.class, Boolean.TYPE};
+      Method setWindowCanFullScreen =
+        fsuClass.getMethod("setWindowCanFullScreen", argClasses);
+      setWindowCanFullScreen.invoke(fsuClass, this, true);
+
+      canDoLionFS = true;
+    } catch (Exception e) {
+      vlog.debug("Could not enable OS X 10.7+ full-screen mode: " +
+                 e.getMessage());
+      
+    }
+  }
+
+  public void toggleLionFS() {
+    try {
+      Class appClass = Class.forName("com.apple.eawt.Application");
+      Method getApplication = appClass.getMethod("getApplication",
+                                                 (Class[])null);
+      Object app = getApplication.invoke(appClass);
+      Method requestToggleFullScreen =
+        appClass.getMethod("requestToggleFullScreen", Window.class);
+      requestToggleFullScreen.invoke(app, this);
+    } catch (Exception e) {
+      vlog.debug("Could not toggle OS X 10.7+ full-screen mode: " +
+                 e.getMessage());
+    }
+  }
+
   public void setChild(DesktopWindow child) {
     sp.getViewport().setView(child);
   }
@@ -126,11 +174,13 @@
       GraphicsEnvironment ge =
         GraphicsEnvironment.getLocalGraphicsEnvironment();
       GraphicsDevice gd = ge.getDefaultScreenDevice();
-      gd.setFullScreenWindow(fullScreenWindow);
+      if (gd.isFullScreenSupported())
+        gd.setFullScreenWindow(fullScreenWindow);
   }
 
   CConn cc;
   JScrollPane sp;
+  boolean canDoLionFS;
   static LogWriter vlog = new LogWriter("Viewport");
 }
 
diff --git a/java/com/tigervnc/vncviewer/VncViewer.java b/java/com/tigervnc/vncviewer/VncViewer.java
index 89bc94e..8a1f930 100644
--- a/java/com/tigervnc/vncviewer/VncViewer.java
+++ b/java/com/tigervnc/vncviewer/VncViewer.java
@@ -1,6 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
+ * Copyright (C) 2011-2013 D. R. Commander.  All Rights Reserved.
  * Copyright (C) 2011-2013 Brian P. Hinz
  *
  * This is free software; you can redistribute it and/or modify
@@ -68,6 +68,8 @@
   public static final Image logoImage = logoIcon.getImage();
   public static final InputStream timestamp =
     VncViewer.class.getResourceAsStream("timestamp");
+  public static final String os = 
+    System.getProperty("os.name").toLowerCase();
 
   public static void setLookAndFeel() {
     try {
@@ -392,6 +394,12 @@
     exit(0);
   }
 
+  // On Mac systems, setting this parameter will force the use of the old
+  // (pre-Lion) full-screen mode, even if the viewer is running on OS X 10.7
+  // "Lion" or later.
+  static BoolParameter noLionFS
+  = new BoolParameter("NoLionFS", null, false);
+
   BoolParameter useLocalCursor
   = new BoolParameter("UseLocalCursor",
                       "Render the mouse cursor locally",