diff --git a/build/shared/lib/defaults.txt b/build/shared/lib/defaults.txt index 015201a03..a7fd61f0c 100644 --- a/build/shared/lib/defaults.txt +++ b/build/shared/lib/defaults.txt @@ -185,7 +185,8 @@ run.options.bits.macosx = 32 # Index of the display to use for running sketches (starts at 1). # Kept this 1-indexed because older vesions of Processing were setting # the preference even before it was being used. -run.display = 0 +# -1 means the default display, 0 means all displays +run.display = -1 # set internally #run.window.bgcolor= diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index b3eeac159..9fca93e29 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -105,7 +105,6 @@ public class PApplet implements PConstants { //{ /** * Full name of the Java version (i.e. 1.5.0_11). - * Prior to 0125, this was only the first three digits. */ public static final String javaVersionName = System.getProperty("java.version"); @@ -690,11 +689,11 @@ public class PApplet implements PConstants { static public final String ARGS_DISPLAY = "--display"; - static public final String ARGS_BGCOLOR = "--bgcolor"; + static public final String ARGS_SPAN_DISPLAYS = "--span"; - static public final String ARGS_FULL_SCREEN = "--full-screen"; + static public final String ARGS_WINDOW_COLOR = "--window-color"; - static public final String ARGS_SPAN_SCREENS = "--span"; + static public final String ARGS_PRESENT = "--present"; static public final String ARGS_STOP_COLOR = "--stop-color"; @@ -810,13 +809,20 @@ public class PApplet implements PConstants { boolean insideSettings; String renderer = JAVA2D; - int quality = 2; +// int quality = 2; + int smooth = 1; boolean fullScreen; - boolean spanDisplays; - int displayIndex; +// boolean spanDisplays; + int display; // set to SPAN when using all displays + String outputPath; OutputStream outputStream; + // Background default needs to be different from the default value in + // PGraphics.backgroundColor, otherwise size(100, 100) bg spills over. + // https://github.com/processing/processing/issues/2297 + int windowColor = 0xffDDDDDD; + boolean insideSettings(Object... args) { if (insideSettings) { @@ -839,42 +845,48 @@ public class PApplet implements PConstants { insideSettings = true; // Workaround for https://github.com/processing/processing/issues/3295 - // until we resolved https://github.com/processing/processing/issues/3296 + // until we resolve https://github.com/processing/processing/issues/3296 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice device = ge.getDefaultScreenDevice(); GraphicsDevice[] devices = ge.getScreenDevices(); - // default or unparsed will be -1 - if (displayIndex >= 0 && displayIndex < devices.length) { - device = devices[displayIndex]; + + // Default or unparsed will be -1, spanning will be 0, actual displays will + // be numbered from 1 because it's too weird to say "display 0" in prefs. + if (display > 0 && display <= devices.length) { + device = devices[display-1]; } DisplayMode displayMode = device.getDisplayMode(); displayWidth = displayMode.getWidth(); displayHeight = displayMode.getHeight(); + // Here's where size(), fullScreen(), smooth(N) and noSmooth() might + // be called, conjuring up the demons of various rendering configurations. settings(); + insideSettings = false; } /** Override this method to call size() when not using the PDE. */ public void settings() { - size(DEFAULT_WIDTH, DEFAULT_HEIGHT, JAVA2D); + // is this necessary? (doesn't appear to be, so removing) + //size(DEFAULT_WIDTH, DEFAULT_HEIGHT, JAVA2D); } - public int sketchWidth() { + final public int sketchWidth() { //return DEFAULT_WIDTH; return width; } - public int sketchHeight() { + final public int sketchHeight() { //return DEFAULT_HEIGHT; return height; } - public String sketchRenderer() { + final public String sketchRenderer() { //return JAVA2D; return renderer; } @@ -887,46 +899,55 @@ public class PApplet implements PConstants { // smoothing at any given time. It's also a bit like getFill() would return // true/false for whether fill was enabled, getFillColor() would return the // color itself. Or at least that's what I can recall at the moment. [fry] - public int sketchQuality() { - //return 2; - return quality; +// public int sketchQuality() { +// //return 2; +// return quality; +// } + // smoothing 1 is default.. 0 is none.. 2,4,8 depend on renderer + final public int sketchSmooth() { + return smooth; } - public boolean sketchFullScreen() { + final public boolean sketchFullScreen() { //return false; return fullScreen; } - // Could be named 'screen' instead of display since it's the people using - // full screen who will be looking for it. On the other hand, screenX/Y/Z - // makes things confusing, and if 'displayIndex' exists... - public boolean sketchSpanDisplays() { - //return false; - return spanDisplays; +// // Could be named 'screen' instead of display since it's the people using +// // full screen who will be looking for it. On the other hand, screenX/Y/Z +// // makes things confusing, and if 'displayIndex' exists... +// public boolean sketchSpanDisplays() { +// //return false; +// return spanDisplays; +// } + + + // Using num instead of index since the latter usually refers 0-indexed lists + // SPAN is used when using all displays + final public int sketchDisplay() { + return display; } - // Or should this be sketchDisplayNum instead of sketchDisplayIndex? - // (Index seems weird, but we don't use 'num' anywhere.) - public int sketchDisplayIndex() { - return displayIndex; - } - - - public String sketchOutputPath() { + final public String sketchOutputPath() { //return null; return outputPath; } - public OutputStream sketchOutputStream() { + final public OutputStream sketchOutputStream() { //return null; return outputStream; } + final public int sketchWindowColor() { + return windowColor; + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -935,6 +956,7 @@ public class PApplet implements PConstants { } + // TODO should this join the sketchXxxx() functions specific to settings()? public void orientation(int which) { // ignore calls to the orientation command } @@ -1485,6 +1507,16 @@ public class PApplet implements PConstants { */ + public void fullScreen(String renderer) { + + } + + + public void fullScreen(String renderer, int display) { + + } + + /** * ( begin auto-generated from size.xml ) * @@ -9447,38 +9479,46 @@ public class PApplet implements PConstants { *
    * Parameters useful for launching or also used by the PDE:
    *
-   * --location=x,y        upper-lefthand corner of where the applet
-   *                       should appear on screen. if not used,
-   *                       the default is to center on the main screen.
+   * --location=x,y         Upper-lefthand corner of where the applet
+   *                        should appear on screen. If not used,
+   *                        the default is to center on the main screen.
    *
-   * --full-screen         put the applet into full screen "present" mode.
+   * --present              Presentation mode: blanks the entire screen and
+   *                        shows the sketch by itself. If the sketch is
+   *                        smaller than the screen, the background around it
+   *                        will use the --window-color setting.
    *
-   * --hide-stop           use to hide the stop button in situations where
-   *                       you don't want to allow users to exit. also
-   *                       see the FAQ on information for capturing the ESC
-   *                       key when running in presentation mode.
+   * --hide-stop            Use to hide the stop button in situations where
+   *                        you don't want to allow users to exit. also
+   *                        see the FAQ on information for capturing the ESC
+   *                        key when running in presentation mode.
    *
-   * --stop-color=#xxxxxx  color of the 'stop' text used to quit an
-   *                       sketch when it's in present mode.
+   * --stop-color=#xxxxxx   Color of the 'stop' text used to quit an
+   *                        sketch when it's in present mode.
    *
-   * --bgcolor=#xxxxxx     background color of the window.
+   * --window-color=#xxxxxx Background color of the window. The color used
+   *                        around the sketch when it's smaller than the
+   *                        minimum window size for the OS, and the matte
+   *                        color when using 'present' mode.
    *
-   * --sketch-path         location of where to save files from functions
-   *                       like saveStrings() or saveFrame(). defaults to
-   *                       the folder that the java application was
-   *                       launched from, which means if this isn't set by
-   *                       the pde, everything goes into the same folder
-   *                       as processing.exe.
+   * --sketch-path          location of where to save files from functions
+   *                        like saveStrings() or saveFrame(). defaults to
+   *                        the folder that the java application was
+   *                        launched from, which means if this isn't set by
+   *                        the pde, everything goes into the same folder
+   *                        as processing.exe.
    *
-   * --display=n           set what display should be used by this sketch.
-   *                       displays are numbered starting from 0.
+   * --display=n            set what display should be used by this sketch.
+   *                        displays are numbered starting from 1.
+   *
+   * --span                 Makes the sketch full screen across all displays.
    *
    * Parameters used by Processing when running via the PDE
    *
-   * --external            set when the applet is being used by the PDE
+   * --external             set when the applet is being used by the PDE
    *
-   * --editor-location=x,y position of the upper-lefthand corner of the
-   *                       editor window, for placement of applet window
+   * --editor-location=x,y  position of the upper-lefthand corner of the
+   *                        editor window, for placement of applet window
    *
    * All parameters *after* the sketch class name are passed to the sketch
    * itself and available from its 'args' array while the sketch is running.
@@ -9555,13 +9595,13 @@ public class PApplet implements PConstants {
     int[] editorLocation = null;
 
     String name = null;
-    int backgroundColor = 0;
-    //int stopColor = java.awt.Color.GRAY.getRGB();
+    int windowColor = 0;
     int stopColor = 0xff808080;
     boolean hideStop = false;
 
-    int displayIndex = -1;  // -1 means use default, b/c numbered from 0
-    boolean fullScreen = false;
+    int displayIndex = -1;  // use default
+//    boolean fullScreen = false;
+    boolean present = false;
     boolean spanDisplays = false;
 
     String param = null, value = null;
@@ -9584,12 +9624,12 @@ public class PApplet implements PConstants {
             System.err.println("Could not parse " + value + " for " + ARGS_DISPLAY);
           }
 
-        } else if (param.equals(ARGS_BGCOLOR)) {
+        } else if (param.equals(ARGS_WINDOW_COLOR)) {
           if (value.charAt(0) == '#' && value.length() == 7) {
             value = value.substring(1);
-            backgroundColor = 0xff000000 | Integer.parseInt(value, 16);
+            windowColor = 0xff000000 | Integer.parseInt(value, 16);
           } else {
-            System.err.println(ARGS_BGCOLOR + " should be a # followed by six digits");
+            System.err.println(ARGS_WINDOW_COLOR + " should be a # followed by six digits");
           }
 
         } else if (param.equals(ARGS_STOP_COLOR)) {
@@ -9608,10 +9648,10 @@ public class PApplet implements PConstants {
         }
 
       } else {
-        if (args[argIndex].equals(ARGS_FULL_SCREEN)) {
-          fullScreen = true;
+        if (args[argIndex].equals(ARGS_PRESENT)) {
+          present = true;
 
-        } else if (args[argIndex].equals(ARGS_SPAN_SCREENS)) {
+        } else if (args[argIndex].equals(ARGS_SPAN_DISPLAYS)) {
           spanDisplays = true;
 
         } else if (args[argIndex].equals(ARGS_HIDE_STOP)) {
@@ -9673,15 +9713,19 @@ public class PApplet implements PConstants {
     // A handful of things that need to be set before init/start.
     sketch.sketchPath = folder;
 
-    sketch.spanDisplays = spanDisplays;
+//    sketch.spanDisplays = spanDisplays;
     // If spanning screens, that means we're also full screen.
-    fullScreen |= spanDisplays;
+//    fullScreen |= spanDisplays;
+    if (spanDisplays) {
+      displayIndex = SPAN;
+//      fullScreen = true;
+    }
 
-    // If the applet doesn't call for full screen, but the command line does,
-    // enable it. Conversely, if the command line does not, don't disable it.
-    // Query the applet to see if it wants to be full screen all the time.
-    //fullScreen |= sketch.sketchFullScreen();
-    sketch.fullScreen |= fullScreen;
+//    // If the applet doesn't call for full screen, but the command line does,
+//    // enable it. Conversely, if the command line does not, don't disable it.
+//    // Query the applet to see if it wants to be full screen all the time.
+//    //fullScreen |= sketch.sketchFullScreen();
+//    sketch.fullScreen |= fullScreen;
 
     // Don't set 'args' to a zero-length array if it should be null [3.0a8]
     if (args.length != argIndex + 1) {
@@ -9692,8 +9736,12 @@ public class PApplet implements PConstants {
 
     sketch.external = external;
 
-    PSurface surface =
-      sketch.initSurface(backgroundColor, displayIndex, fullScreen, spanDisplays);
+    if (windowColor != 0) {
+      sketch.windowColor = windowColor;
+    }
+
+    PSurface surface = sketch.initSurface();
+//      sketch.initSurface(windowColor, displayIndex, fullScreen, spanDisplays);
 
     // Wait until the applet has figured out its width. In a static mode app,
     // everything happens inside setup(), so this will be after setup() has
@@ -9708,7 +9756,7 @@ public class PApplet implements PConstants {
       }
     }
 
-    if (fullScreen) {
+    if (present) {
       if (hideStop) {
         stopColor = 0;  // they'll get the hint
       }
@@ -9723,8 +9771,8 @@ public class PApplet implements PConstants {
   }
 
 
-  protected PSurface initSurface(int backgroundColor, int displayIndex,
-                                 boolean fullScreen, boolean spanDisplays) {
+  protected PSurface initSurface() {/*int backgroundColor, int displayNum,
+                                 boolean fullScreen, boolean spanDisplays) {*/
     g = createPrimaryGraphics();
     surface = g.createSurface();
 
@@ -9755,7 +9803,7 @@ public class PApplet implements PConstants {
         }
       };
 
-      surface.initFrame(this, backgroundColor, displayIndex, fullScreen, spanDisplays);
+      surface.initFrame(this); //, backgroundColor, displayNum, fullScreen, spanDisplays);
       surface.setTitle(getClass().getName());
 
     } else {
diff --git a/core/src/processing/core/PConstants.java b/core/src/processing/core/PConstants.java
index 1afc3b3b3..5a0edc2be 100644
--- a/core/src/processing/core/PConstants.java
+++ b/core/src/processing/core/PConstants.java
@@ -472,6 +472,8 @@ public interface PConstants {
   /** Screen orientation constant for landscape (the hot dog way). */
   static final int LANDSCAPE = 2;
 
+  /** Use with fullScreen() to indicate all available displays. */
+  static final int SPAN = 0;
 
   // cursor types
 
diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java
index ff3b92b71..12df26168 100644
--- a/core/src/processing/core/PGraphics.java
+++ b/core/src/processing/core/PGraphics.java
@@ -163,6 +163,9 @@ public class PGraphics extends PImage implements PConstants {
   /// the anti-aliasing level for renderers that support it
   public int quality;
 
+//  public int smooth;
+
+
   // ........................................................
 
   /// true if defaults() has been called a first time
@@ -701,7 +704,7 @@ public class PGraphics extends PImage implements PConstants {
     this.parent = parent;
     // Some renderers (OpenGL) need to know what smoothing level will be used
     // before the rendering surface is even created.
-    quality = parent.sketchQuality();
+    quality = parent.sketchSmooth();
   }
 
 
diff --git a/core/src/processing/core/PSurface.java b/core/src/processing/core/PSurface.java
index 0dfb382fe..1c5270cf2 100644
--- a/core/src/processing/core/PSurface.java
+++ b/core/src/processing/core/PSurface.java
@@ -34,12 +34,6 @@ public interface PSurface {
   static public final int MIN_WINDOW_WIDTH = 128;
   static public final int MIN_WINDOW_HEIGHT = 128;
 
-  // Background default needs to be different from the default value in
-  // PGraphics.backgroundColor, otherwise size(100, 100) bg spills over.
-  // https://github.com/processing/processing/issues/2297
-  //static final Color WINDOW_BGCOLOR = new Color(0xDD, 0xDD, 0xDD);
-  static final int WINDOW_BGCOLOR = 0xffDDDDDD;
-
   // renderer that doesn't draw to the screen
   public void initOffscreen(PApplet sketch);
 
@@ -48,8 +42,9 @@ public interface PSurface {
   //public Component initComponent(PApplet sketch);
 
   //public Frame initFrame(PApplet sketch, Color backgroundColor,
-  public void initFrame(PApplet sketch, int backgroundColor,
-                        int deviceIndex, boolean fullScreen, boolean spanDisplays);
+//  public void initFrame(PApplet sketch, int backgroundColor,
+//                        int deviceIndex, boolean fullScreen, boolean spanDisplays);
+  public void initFrame(PApplet sketch);
 
   //
 
diff --git a/core/src/processing/core/PSurfaceAWT.java b/core/src/processing/core/PSurfaceAWT.java
index 6ad6c8ac6..60f5b6630 100644
--- a/core/src/processing/core/PSurfaceAWT.java
+++ b/core/src/processing/core/PSurfaceAWT.java
@@ -390,20 +390,21 @@ public class PSurfaceAWT extends PSurfaceNone {
 
 
   @Override
-  public void initFrame(PApplet sketch, int backgroundColor,
-                        int deviceIndex, boolean fullScreen, boolean spanDisplays) {
+  public void initFrame(PApplet sketch) {/*, int backgroundColor,
+                        int deviceIndex, boolean fullScreen, boolean spanDisplays) {*/
     this.sketch = sketch;
 
     GraphicsEnvironment environment =
       GraphicsEnvironment.getLocalGraphicsEnvironment();
 
-    if (deviceIndex >= 0) {  // if -1, use the default device
+    int displayNum = sketch.sketchDisplay();
+    if (displayNum > 0) {  // if -1, use the default device
       GraphicsDevice[] devices = environment.getScreenDevices();
-      if (deviceIndex < devices.length) {
-        displayDevice = devices[deviceIndex];
+      if (displayNum <= devices.length) {
+        displayDevice = devices[displayNum - 1];
       } else {
         System.err.format("Display %d does not exist, " +
-          "using the default display instead.", deviceIndex);
+          "using the default display instead.", displayNum);
         for (int i = 0; i < devices.length; i++) {
           System.err.format("Display %d is %s\n", i, devices[i]);
         }
@@ -416,6 +417,7 @@ public class PSurfaceAWT extends PSurfaceNone {
     // Need to save the window bounds at full screen,
     // because pack() will cause the bounds to go to zero.
     // http://dev.processing.org/bugs/show_bug.cgi?id=923
+    boolean spanDisplays = sketch.sketchDisplay() == PConstants.SPAN;
     screenRect = spanDisplays ? getDisplaySpan() :
       displayDevice.getDefaultConfiguration().getBounds();
     // DisplayMode doesn't work here, because we can't get the upper-left
@@ -429,6 +431,7 @@ public class PSurfaceAWT extends PSurfaceNone {
     sketchWidth = sketch.sketchWidth();
     sketchHeight = sketch.sketchHeight();
 
+    boolean fullScreen = sketch.sketchFullScreen();
     // Sketch has already requested to be the same as the screen's
     // width and height, so let's roll with full screen mode.
     if (screenRect.width == sketchWidth &&
@@ -451,12 +454,12 @@ public class PSurfaceAWT extends PSurfaceNone {
 //    ((JFrame) frame).getContentPane().setBackground(WINDOW_BGCOLOR);
 //    // Cannot call setResizable(false) until later due to OS X (issue #467)
 
-    // Removed code above, also removed from what's now in the placeXxxx()
-    // methods. Not sure why it was being double-set; hopefully anachronistic.
-    if (backgroundColor == 0) {
-      backgroundColor = WINDOW_BGCOLOR;
-    }
-    frame.getContentPane().setBackground(new Color(backgroundColor, false));
+//    // Removed code above, also removed from what's now in the placeXxxx()
+//    // methods. Not sure why it was being double-set; hopefully anachronistic.
+//    if (backgroundColor == 0) {
+//      backgroundColor = WINDOW_BGCOLOR;
+//    }
+    frame.getContentPane().setBackground(new Color(sketch.sketchWindowColor(), false));
 
     // Put the p5 logo in the Frame's corner to override the Java coffee cup.
     setIconImage(frame);
diff --git a/core/src/processing/core/PSurfaceFX.java b/core/src/processing/core/PSurfaceFX.java
index f62c7335c..249f41625 100644
--- a/core/src/processing/core/PSurfaceFX.java
+++ b/core/src/processing/core/PSurfaceFX.java
@@ -193,9 +193,9 @@ public class PSurfaceFX implements PSurface {
 
 
   //public Frame initFrame(PApplet sketch, java.awt.Color backgroundColor,
-  public void initFrame(PApplet sketch, int backgroundColor,
+  public void initFrame(PApplet sketch) {/*, int backgroundColor,
                          int deviceIndex, boolean fullScreen,
-                         boolean spanDisplays) {
+                         boolean spanDisplays) {*/
     this.sketch = sketch;
     PApplicationFX.surface = this;
     //Frame frame = new DummyFrame();
diff --git a/core/src/processing/core/PSurfaceNone.java b/core/src/processing/core/PSurfaceNone.java
index 79f206e9b..c9695140c 100644
--- a/core/src/processing/core/PSurfaceNone.java
+++ b/core/src/processing/core/PSurfaceNone.java
@@ -58,9 +58,9 @@ public class PSurfaceNone implements PSurface {
 
 
   @Override
-  public void initFrame(PApplet sketch, int backgroundColor,
+  public void initFrame(PApplet sketch) {/*, int backgroundColor,
                         int deviceIndex, boolean fullScreen,
-                        boolean spanDisplays) {
+                        boolean spanDisplays) {*/
     //this.sketch = sketch;
     throw new IllegalStateException("initFrame() not available with " +
                                     getClass().getSimpleName());
diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java
index 512cbbd61..c834dead4 100644
--- a/core/src/processing/opengl/PGL.java
+++ b/core/src/processing/opengl/PGL.java
@@ -35,7 +35,6 @@ import java.util.Arrays;
 
 import processing.core.PApplet;
 import processing.core.PGraphics;
-import processing.core.PSurface;
 
 
 /**
@@ -589,16 +588,15 @@ public abstract class PGL {
 
 
   IntBuffer labelTex;
-  protected void endDraw(boolean clear0) {
+  protected void endDraw(boolean clear0, int windowColor) {
     if (fboLayerInUse) {
       syncBackTexture();
 
       // Draw the contents of the back texture to the screen framebuffer.
       bindFramebufferImpl(FRAMEBUFFER, 0);
 
-
       if (presentMode) {
-        int argb = PSurface.WINDOW_BGCOLOR;
+        int argb = windowColor;
         float a = ((argb >> 24) & 0xff)  / 255.0f;
         float r = ((argb >> 16) & 0xff) / 255.0f;
         float g = ((argb >> 8) & 0xff) / 255.0f;
diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java
index 29c8e2b45..8eba960b0 100644
--- a/core/src/processing/opengl/PGraphicsOpenGL.java
+++ b/core/src/processing/opengl/PGraphicsOpenGL.java
@@ -6524,7 +6524,7 @@ public class PGraphicsOpenGL extends PGraphics {
 
 
   protected void endOnscreenDraw() {
-    pgl.endDraw(clearColorBuffer0);
+    pgl.endDraw(clearColorBuffer0, parent.sketchWindowColor());
   }
 
 
diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java
index 0929ff2fb..167e980c8 100644
--- a/core/src/processing/opengl/PSurfaceJOGL.java
+++ b/core/src/processing/opengl/PSurfaceJOGL.java
@@ -8,6 +8,7 @@ import java.awt.Point;
 //import java.awt.Frame;
 import java.awt.Rectangle;
 import java.util.ArrayList;
+import java.util.List;
 
 import com.jogamp.common.util.IOUtil.ClassResources;
 import com.jogamp.nativewindow.NativeSurface;
@@ -88,9 +89,9 @@ public class PSurfaceJOGL implements PSurface {
   }
 
 
-  public void initFrame(PApplet sketch, int backgroundColor,
+  public void initFrame(PApplet sketch) {/*, int backgroundColor,
                         int deviceIndex, boolean fullScreen,
-                        boolean spanDisplays) {
+                        boolean spanDisplays) {*/
     this.sketch = sketch;
 
     setIconImages();
@@ -100,7 +101,7 @@ public class PSurfaceJOGL implements PSurface {
     Screen screen = NewtFactory.createScreen(display, 0);
     screen.addReference();
 
-    ArrayList monitors = new ArrayList();
+    List monitors = new ArrayList();
     GraphicsEnvironment environment =
       GraphicsEnvironment.getLocalGraphicsEnvironment();
     GraphicsDevice[] devices = environment.getScreenDevices();
@@ -142,14 +143,15 @@ public class PSurfaceJOGL implements PSurface {
 
 //    System.out.println("*******************************");
 
-    if (deviceIndex >= 0) {  // if -1, use the default device
-      if (deviceIndex < monitors.size()) {
-        displayDevice = monitors.get(deviceIndex);
+    int displayNum = sketch.sketchDisplay();
+    if (displayNum > 0) {  // if -1, use the default device
+      if (displayNum <= monitors.size()) {
+        displayDevice = monitors.get(displayNum - 1);
       } else {
         System.err.format("Display %d does not exist, " +
-          "using the default display instead.", deviceIndex);
+          "using the default display instead.", displayNum);
         for (int i = 0; i < monitors.size(); i++) {
-          System.err.format("Display %d is %s\n", i, monitors.get(i));
+          System.err.format("Display %d is %s\n", i+1, monitors.get(i));
         }
       }
     }
@@ -230,13 +232,17 @@ public class PSurfaceJOGL implements PSurface {
 //    int screenWidth = screen.getWidth();
 //    int screenHeight = screen.getHeight();
 
-    screenRect = spanDisplays ? new Rectangle(0, 0, screen.getWidth(), screen.getHeight()) :
-                                new Rectangle(0, 0, displayDevice.getViewportInWindowUnits().getWidth(),
-                                                    displayDevice.getViewportInWindowUnits().getHeight());
+    boolean spanDisplays = sketch.sketchDisplay() == PConstants.SPAN;
+    screenRect = spanDisplays ?
+      new Rectangle(0, 0, screen.getWidth(), screen.getHeight()) :
+      new Rectangle(0, 0,
+                    displayDevice.getViewportInWindowUnits().getWidth(),
+                    displayDevice.getViewportInWindowUnits().getHeight());
 
     sketch.displayWidth = screenRect.width;
     sketch.displayHeight = screenRect.height;
 
+    boolean fullScreen = sketch.sketchFullScreen();
     // Sketch has already requested to be the same as the screen's
     // width and height, so let's roll with full screen mode.
     if (screenRect.width == sketchWidth &&
diff --git a/core/todo.txt b/core/todo.txt
index ba301aff6..2579e92c9 100644
--- a/core/todo.txt
+++ b/core/todo.txt
@@ -1,6 +1,13 @@
 0237 (3.0a10)
 X retain original java.awt.Frame when it's in use
 X set frame icon images for Java2D (dock and cmd-tab) 
+X size() inside setup() can only have numbers
+X   size() inside settings() is left alone and can do whatever it wants
+X   comments are being removed before size() is getting checked
+X     probably remove anything inside settings() as well?
+o add imageSmooth()?
+o   https://github.com/processing/processing/issues/1272
+X   decided no, again
 
 fixed earlier/can no longer reproduce
 X strips when rendering spheres with lights and anti-aliasing
@@ -28,21 +35,30 @@ X set icon for OpenGL windows
 X   https://github.com/processing/processing/issues/3348
 X key problem with DELETE, BACKSPACE and CMD in P3D / P2D
 X   https://github.com/processing/processing/issues/3352
-_ save() and saveFrame() with OPENGL renderer fails
-_   https://github.com/processing/processing/issues/3334
+X save() and saveFrame() with OPENGL renderer fails
+X   https://github.com/processing/processing/issues/3334
 
 
 beta
-_ size() inside setup() can only have numbers
-_   size() inside settings() is left alone and can do whatever it wants
-_   comments are being removed before size() is getting checked
-_     probably remove anything inside settings() as well?
-_ fullScreen() method
-_   take display into account for fullScreen()
+X sketchXxxx() methods are final, need to move folks away from these
+_ fix up handling of fullScreen()
+_   https://github.com/processing/processing/issues/3296
+_   right now using a (display ignoring) hack to displayWidth/Height
+X   maybe we use the AWT screen sizes first, then match the others w/ em?
+_   https://docs.oracle.com/javafx/2/api/javafx/stage/Screen.html
+X   --full-screen replaced with --present (to untangle things)
+_     if you want full screen, use the fullScreen() method
+X instead of all these sketchXxxx() methods, should we have sketchSetting()
+_   and an internal dictionary that stores them all?
+_     intParam(), stringParam() and setParam()? 
+o   or sketchInt() or settingsInt()?
+o   too much soup inside main() to handle arg parsing and passing to the sketch
+X   moved things to settings()
 _ noSmooth()
 _   can only be called inside setup(), show warning elsewhere
 _   is lifted out of setup() and into settings()
 _   goes before the first beginDraw() with createGraphics()
+_   sketchQuality() needs to be rooted out
 _ sort out display stuff (bug in the numbering in 3.0a9)
 _ Text looks blurry in GL Retina (andres)
 _   https://github.com/processing/processing/issues/2739
@@ -73,15 +89,6 @@ _ sketch window briefly appears on top left corner when using OpenGL
 _   https://github.com/processing/processing/issues/3308
 _ looks like we're off by 1 on monitor numbering 
 _   https://github.com/processing/processing/issues/3309
-_ need a better option for using full screen
-_   https://github.com/processing/processing/issues/3296
-_   right now using a (display ignoring) hack to displayWidth/Height
-_   maybe we use the AWT screen sizes first, then match the others w/ em?
-_   https://docs.oracle.com/javafx/2/api/javafx/stage/Screen.html
-_ instead of all these sketchXxxx() methods, should we have sketchSetting()
-_   and an internal dictionary that stores them all?
-_   or sketchInt() or settingsInt()?
-_   too much soup inside main() to handle arg parsing and passing to the sketch
 _ update documentation to say "don't override sketchXxxx() methods"
 _ sketch window is not placed at correct location when running a second time
 _   https://github.com/processing/processing/issues/3125
@@ -146,8 +153,6 @@ _ when did setPath() sneak into PShape? API is nothing like anything else
 _   probably from the material stuff, but we need to fix that
 _ ortho function is broken
 _   https://github.com/processing/processing/issues/1278
-_ add imageSmooth()?
-_   https://github.com/processing/processing/issues/1272
 
 
 full screen
diff --git a/java/src/processing/mode/java/JavaBuild.java b/java/src/processing/mode/java/JavaBuild.java
index c6ad74259..cda74323e 100644
--- a/java/src/processing/mode/java/JavaBuild.java
+++ b/java/src/processing/mode/java/JavaBuild.java
@@ -249,7 +249,7 @@ public class JavaBuild {
     // in the preprocessor. Those are used in preproc.write() so that they
     // can be used to add methods (settings() or sketchXxxx())
     //String[] sizeParts =
-    SizeInfo sizeInfo =
+    SurfaceInfo sizeInfo =
       preprocessor.initSketchSize(sketch.getMainProgram(), sizeWarning);
     if (sizeInfo == null) {
       // An error occurred while trying to pull out the size, so exit here
diff --git a/java/src/processing/mode/java/preproc/PdePreprocessor.java b/java/src/processing/mode/java/preproc/PdePreprocessor.java
index 4c0daf217..a41594824 100644
--- a/java/src/processing/mode/java/preproc/PdePreprocessor.java
+++ b/java/src/processing/mode/java/preproc/PdePreprocessor.java
@@ -151,7 +151,7 @@ public class PdePreprocessor {
   protected Mode mode;
   Set foundMethods;
 
-  SizeInfo sizeInfo;
+  SurfaceInfo sizeInfo;
 
 
   /**
@@ -201,7 +201,7 @@ public class PdePreprocessor {
   }
 
 
-  public SizeInfo initSketchSize(String code,
+  public SurfaceInfo initSketchSize(String code,
                                  boolean sizeWarning) throws SketchException {
     sizeInfo = parseSketchSize(code, sizeWarning);
     return sizeInfo;
@@ -252,7 +252,7 @@ public class PdePreprocessor {
    * @param fussy true if it should show an error message if bad size()
    * @return null if there was an error, otherwise an array (might contain some/all nulls)
    */
-  static public SizeInfo parseSketchSize(String code,
+  static public SurfaceInfo parseSketchSize(String code,
                                          boolean fussy) throws SketchException {
     // This matches against any uses of the size() function, whether numbers
     // or variables or whatever. This way, no warning is shown if size() isn't
@@ -312,7 +312,7 @@ public class PdePreprocessor {
       //String[] matches = split on commas, but not commas inside quotes
 
       StringList args = breakCommas(contents[1]);
-      SizeInfo info = new SizeInfo();
+      SurfaceInfo info = new SurfaceInfo();
       info.statement = contents[0];
       info.width = args.get(0).trim();
       info.height = args.get(1).trim();
@@ -347,7 +347,7 @@ public class PdePreprocessor {
     // if no size() found, check for fullScreen()
     contents = PApplet.match(searchArea, FULL_SCREEN_CONTENTS_REGEX);
     if (contents != null) {
-      SizeInfo info = new SizeInfo();
+      SurfaceInfo info = new SurfaceInfo();
       info.statement = contents[0];
       StringList args = breakCommas(contents[1]);
       info.renderer = args.get(0).trim();
@@ -360,7 +360,7 @@ public class PdePreprocessor {
 
     // not an error, just no size() specified
     //return new String[] { null, null, null, null, null };
-    return new SizeInfo();
+    return new SurfaceInfo();
   }
 
 
@@ -1001,7 +1001,7 @@ public class PdePreprocessor {
           out.print("\"" + PApplet.ARGS_FULL_SCREEN + "\", ");
 
           String farbe = Preferences.get("run.present.bgcolor");
-          out.print("\"" + PApplet.ARGS_BGCOLOR + "=" + farbe + "\", ");
+          out.print("\"" + PApplet.ARGS_WINDOW_COLOR + "=" + farbe + "\", ");
 
           if (Preferences.getBoolean("export.application.stop")) {
             farbe = Preferences.get("run.present.stop.color");
diff --git a/java/src/processing/mode/java/preproc/SizeInfo.java b/java/src/processing/mode/java/preproc/SurfaceInfo.java
similarity index 96%
rename from java/src/processing/mode/java/preproc/SizeInfo.java
rename to java/src/processing/mode/java/preproc/SurfaceInfo.java
index a461d241f..a59e9f02c 100644
--- a/java/src/processing/mode/java/preproc/SizeInfo.java
+++ b/java/src/processing/mode/java/preproc/SurfaceInfo.java
@@ -27,13 +27,16 @@ import processing.app.Base;
 import processing.core.PApplet;
 
 
-public class SizeInfo {
+public class SurfaceInfo {
   String statement;
   String width;
   String height;
   String renderer;
   String path;
+
   String display;
+  /** null for nothing in setup(), 0 for noSmooth(), N for smooth(N) */
+  Integer quality;
 
 
   boolean hasOldSyntax() {
diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java
index a99dddd8c..c157ebadf 100644
--- a/java/src/processing/mode/java/runner/Runner.java
+++ b/java/src/processing/mode/java/runner/Runner.java
@@ -385,7 +385,7 @@ public class Runner implements MessageConsumer {
 //        }
         params.add(PApplet.ARGS_STOP_COLOR + "=" +
                    Preferences.get("run.present.stop.color"));
-        params.add(PApplet.ARGS_BGCOLOR + "=" +
+        params.add(PApplet.ARGS_WINDOW_COLOR + "=" +
                    Preferences.get("run.present.bgcolor"));
       }