You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2011/01/11 14:40:22 UTC

svn commit: r1057619 [1/2] - in /pivot/branches/3.x: scene-platform-awt/ scene-platform-awt/src/ scene-platform-awt/src/org/ scene-platform-awt/src/org/apache/ scene-platform-awt/src/org/apache/pivot/ scene-platform-awt/src/org/apache/pivot/scene/ scen...

Author: gbrown
Date: Tue Jan 11 13:40:20 2011
New Revision: 1057619

URL: http://svn.apache.org/viewvc?rev=1057619&view=rev
Log:
Continue renaming platform projects; add Terra skin project.

Added:
    pivot/branches/3.x/scene-platform-awt/
    pivot/branches/3.x/scene-platform-awt/.classpath
    pivot/branches/3.x/scene-platform-awt/.project
    pivot/branches/3.x/scene-platform-awt/src/
    pivot/branches/3.x/scene-platform-awt/src/org/
    pivot/branches/3.x/scene-platform-awt/src/org/apache/
    pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/
    pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/
    pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTGraphics.java
    pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTPlatform.java
    pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTRaster.java
    pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTStageHost.java
    pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/CharSequenceCharacterIterator.java
    pivot/branches/3.x/scene-platform-swt/
    pivot/branches/3.x/scene-platform-swt/.classpath
    pivot/branches/3.x/scene-platform-swt/.project
    pivot/branches/3.x/scene-platform-swt/src/
    pivot/branches/3.x/scene-platform-swt/src/org/
    pivot/branches/3.x/scene-platform-swt/src/org/apache/
    pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/
    pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/
    pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTGraphics.java
    pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTPlatform.java
    pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTRaster.java
    pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTStageHost.java
    pivot/branches/3.x/ui-platform-awt/
    pivot/branches/3.x/ui-platform-awt/.classpath
    pivot/branches/3.x/ui-platform-awt/.project
    pivot/branches/3.x/ui-platform-awt/src/
    pivot/branches/3.x/ui-platform-awt/src/org/
    pivot/branches/3.x/ui-platform-awt/src/org/apache/
    pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/
    pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/
    pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/BrowserApplicationContext.java
    pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/DesktopApplicationContext.java
    pivot/branches/3.x/ui-platform-swt/
    pivot/branches/3.x/ui-platform-swt/.classpath
    pivot/branches/3.x/ui-platform-swt/.project
    pivot/branches/3.x/ui-platform-swt/src/
    pivot/branches/3.x/ui-platform-swt/src/org/
    pivot/branches/3.x/ui-platform-swt/src/org/apache/
    pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/
    pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/
    pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/DesktopApplicationContext.java
    pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/PluginApplicationContext.java
    pivot/branches/3.x/ui-skin-terra/
    pivot/branches/3.x/ui-skin-terra/.classpath
    pivot/branches/3.x/ui-skin-terra/.project
    pivot/branches/3.x/ui-skin-terra/.settings/
    pivot/branches/3.x/ui-skin-terra/.settings/org.eclipse.jdt.core.prefs
    pivot/branches/3.x/ui-skin-terra/src/

Added: pivot/branches/3.x/scene-platform-awt/.classpath
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-awt/.classpath?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-awt/.classpath (added)
+++ pivot/branches/3.x/scene-platform-awt/.classpath Tue Jan 11 13:40:20 2011
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/core"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/scene"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: pivot/branches/3.x/scene-platform-awt/.project
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-awt/.project?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-awt/.project (added)
+++ pivot/branches/3.x/scene-platform-awt/.project Tue Jan 11 13:40:20 2011
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>scene-platform-awt</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTGraphics.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTGraphics.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTGraphics.java (added)
+++ pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTGraphics.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,397 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.scene;
+
+import java.awt.AlphaComposite;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+
+import org.apache.pivot.scene.Bounds;
+import org.apache.pivot.scene.Color;
+import org.apache.pivot.scene.Font;
+import org.apache.pivot.scene.Graphics;
+import org.apache.pivot.scene.Paint;
+import org.apache.pivot.scene.PathGeometry;
+import org.apache.pivot.scene.Platform;
+import org.apache.pivot.scene.SolidColorPaint;
+import org.apache.pivot.scene.Stroke;
+import org.apache.pivot.scene.Transform;
+import org.apache.pivot.scene.media.Raster;
+
+/**
+ * AWT graphics implementation.
+ */
+public class AWTGraphics extends Graphics {
+    private Graphics2D graphics2D;
+
+    private float alpha;
+    private CompositeOperation compositeOperation;
+    private boolean antiAliased;
+    private Stroke stroke;
+    private Paint paint;
+    private Font font;
+
+    private Line2D.Float line2D = new Line2D.Float();
+    private Rectangle2D.Float rectangle2D = new Rectangle2D.Float();
+    private RoundRectangle2D.Float roundRectangle2D = new RoundRectangle2D.Float();
+    private Arc2D.Float arc2D = new Arc2D.Float();
+    private Ellipse2D.Float ellipse2D = new Ellipse2D.Float();
+
+    public AWTGraphics(Graphics2D graphics2D) {
+        if (graphics2D == null) {
+            throw new IllegalArgumentException();
+        }
+
+        this.graphics2D = graphics2D;
+
+        setAlpha(1.0f);
+        setCompositeOperation(CompositeOperation.SOURCE_OVER);
+        setAntiAliased(false);
+        setStroke(new Stroke());
+        setPaint(new SolidColorPaint(Color.BLACK));
+        setFont(Platform.getPlatform().getDefaultFont());
+    }
+
+    // Clipping
+    @Override
+    public void clip(int x, int y, int width, int height) {
+        graphics2D.clipRect(x, y, width, height);
+    }
+
+    @Override
+    public Bounds getClipBounds() {
+        Rectangle clipBounds = graphics2D.getClipBounds();
+        return new Bounds(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);
+    }
+
+    // Compositing
+    @Override
+    public float getAlpha() {
+        return alpha;
+    }
+
+    @Override
+    public void setAlpha(float alpha) {
+        if (alpha < 0
+            || alpha > 1) {
+            throw new IllegalArgumentException("Alpha must be between 0 and 1.");
+        }
+
+        this.alpha = alpha;
+
+        AlphaComposite alphaComposite = (AlphaComposite)graphics2D.getComposite();
+        graphics2D.setComposite(alphaComposite.derive(alpha));
+    }
+
+    @Override
+    public CompositeOperation getCompositeOperation() {
+        return compositeOperation;
+    }
+
+    @Override
+    public void setCompositeOperation(CompositeOperation compositeOperation) {
+        int rule = -1;
+        switch (compositeOperation) {
+            case SOURCE_ATOP: {
+                rule = AlphaComposite.SRC_ATOP;
+                break;
+            }
+
+            case SOURCE_IN: {
+                rule = AlphaComposite.SRC_IN;
+                break;
+            }
+
+            case SOURCE_OUT: {
+                rule = AlphaComposite.SRC_OUT;
+                break;
+            }
+
+            case SOURCE_OVER: {
+                rule = AlphaComposite.SRC_OVER;
+                break;
+            }
+
+            case DESTINATION_ATOP: {
+                rule = AlphaComposite.DST_ATOP;
+                break;
+            }
+
+            case DESTINATION_IN: {
+                rule = AlphaComposite.DST_IN;
+                break;
+            }
+
+            case DESTINATION_OUT: {
+                rule = AlphaComposite.DST_OUT;
+                break;
+            }
+
+            case DESTINATION_OVER: {
+                rule = AlphaComposite.DST_OVER;
+                break;
+            }
+
+            case CLEAR: {
+                rule = AlphaComposite.CLEAR;
+                break;
+            }
+
+            case XOR: {
+                rule = AlphaComposite.XOR;
+                break;
+            }
+        }
+
+        graphics2D.setComposite(AlphaComposite.getInstance(rule, alpha));
+    }
+
+    // Anti-aliasing
+    @Override
+    public boolean isAntiAliased() {
+        return antiAliased;
+    }
+
+    @Override
+    public void setAntiAliased(boolean antiAliased) {
+        this.antiAliased = antiAliased;
+
+        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAliased ?
+            RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
+    }
+
+    // Primitive drawing/filling
+    @Override
+    public Stroke getStroke() {
+        return stroke;
+    }
+
+    @Override
+    public void setStroke(Stroke stroke) {
+        if (stroke == null) {
+            throw new IllegalArgumentException("stroke is null.");
+        }
+
+        graphics2D.setStroke((java.awt.Stroke)stroke.getNativeStroke());
+    }
+
+    @Override
+    public Paint getPaint() {
+        return paint;
+    }
+
+    @Override
+    public void setPaint(Paint paint) {
+        if (paint == null) {
+            throw new IllegalArgumentException("paint is null.");
+        }
+
+        this.paint = paint;
+
+        graphics2D.setPaint((java.awt.Paint)paint.getNativePaint());
+    }
+
+    @Override
+    public void drawLine(float x1, float y1, float x2, float y2) {
+        // TODO Optimize to use drawLine() when appropriate
+
+        line2D.x1 = x1;
+        line2D.y1 = y1;
+        line2D.x2 = x2;
+        line2D.y2 = y2;
+
+        graphics2D.draw(line2D);
+    }
+
+    @Override
+    public void drawRectangle(float x, float y, float width, float height, float cornerRadius) {
+        // TODO Optimize to use drawRect() or drawRoundRect() when appropriate
+
+        if (cornerRadius == 0) {
+            rectangle2D.x = x;
+            rectangle2D.y = y;
+            rectangle2D.width = width;
+            rectangle2D.height = height;
+
+            graphics2D.draw(rectangle2D);
+        } else {
+            roundRectangle2D.x = x;
+            roundRectangle2D.y = y;
+            roundRectangle2D.width = width;
+            roundRectangle2D.height = height;
+            roundRectangle2D.archeight = cornerRadius;
+            roundRectangle2D.arcwidth = cornerRadius;
+
+            graphics2D.draw(roundRectangle2D);
+        }
+    }
+
+    @Override
+    public void drawArc(float x, float y, float width, float height, float start, float extent) {
+        // TODO Optimize to use drawArc() when appropriate
+
+        arc2D.x = x;
+        arc2D.y = y;
+        arc2D.width = width;
+        arc2D.height = height;
+        arc2D.start = start;
+        arc2D.extent = extent;
+
+        graphics2D.draw(arc2D);
+    }
+
+    @Override
+    public void drawEllipse(float x, float y, float width, float height) {
+        // TODO Optimize to use drawOval() when appropriate
+
+        ellipse2D.x = x;
+        ellipse2D.y = y;
+        ellipse2D.width = width;
+        ellipse2D.height = height;
+
+        graphics2D.draw(ellipse2D);
+    }
+
+    @Override
+    public void drawPath(PathGeometry pathGeometry) {
+        graphics2D.draw((Path2D.Float)pathGeometry.getNativePathGeometry());
+    }
+
+    @Override
+    public void fillRectangle(float x, float y, float width, float height, float cornerRadius) {
+        // TODO Optimize to use fillRect() or fillRoundRect() when appropriate
+
+        if (cornerRadius == 0) {
+            rectangle2D.x = x;
+            rectangle2D.y = y;
+            rectangle2D.width = width;
+            rectangle2D.height = height;
+
+            graphics2D.fill(rectangle2D);
+        } else {
+            roundRectangle2D.x = x;
+            roundRectangle2D.y = y;
+            roundRectangle2D.width = width;
+            roundRectangle2D.height = height;
+            roundRectangle2D.archeight = cornerRadius;
+            roundRectangle2D.arcwidth = cornerRadius;
+
+            graphics2D.fill(roundRectangle2D);
+        }
+    }
+
+    @Override
+    public void fillArc(float x, float y, float width, float height, float start, float extent) {
+        // TODO Optimize to use fillArc() when appropriate
+
+        arc2D.x = x;
+        arc2D.y = y;
+        arc2D.width = width;
+        arc2D.height = height;
+        arc2D.start = start;
+        arc2D.extent = extent;
+
+        graphics2D.fill(arc2D);
+    }
+
+    @Override
+    public void fillEllipse(float x, float y, float width, float height) {
+        // TODO Optimize to use drawOval() when appropriate
+
+        ellipse2D.x = x;
+        ellipse2D.y = y;
+        ellipse2D.width = width;
+        ellipse2D.height = height;
+
+        graphics2D.draw(ellipse2D);
+    }
+
+    @Override
+    public void fillPath(PathGeometry pathGeometry) {
+        graphics2D.fill((Path2D.Float)pathGeometry.getNativePathGeometry());
+    }
+
+    @Override
+    public void drawRaster(Raster raster, int x, int y, int width, int height) {
+        graphics2D.drawImage((BufferedImage)raster.getNativeRaster(), x, y, null);
+    }
+
+    // Blitting
+    @Override
+    public void copyArea(int x, int y, int width, int height, int dx, int dy) {
+        graphics2D.copyArea(x, y, width, height, dx, dy);
+    }
+
+    // Text
+    @Override
+    public Font getFont() {
+        return font;
+    }
+
+    @Override
+    public void setFont(Font font) {
+        graphics2D.setFont((java.awt.Font)font.getNativeFont());
+    }
+
+    @Override
+    public void drawText(CharSequence text, int start, int length, float x, float y) {
+        java.awt.Font nativeFont = (java.awt.Font)font.getNativeFont();
+        FontRenderContext fontRenderContext = AWTPlatform.getFontRenderContext();
+        GlyphVector glyphVector = nativeFont.createGlyphVector(fontRenderContext,
+            new CharSequenceCharacterIterator(text, start, start + length));
+
+        graphics2D.drawGlyphVector(glyphVector, x, y);
+    }
+
+    // Transformations
+    @Override
+    public void transform(float m11, float m12, float m21, float m22, float dx, float dy) {
+        // TODO
+    }
+
+    @Override
+    public Transform getCurrentTransform() {
+        // TODO
+        return null;
+    }
+
+    // Creation/disposal
+    @Override
+    public Graphics create() {
+        return new AWTGraphics((Graphics2D)graphics2D.create());
+    }
+
+    @Override
+    public void dispose() {
+        graphics2D.dispose();
+    }
+
+    @Override
+    public Object getNativeGraphics() {
+        return graphics2D;
+    }
+}

Added: pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTPlatform.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTPlatform.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTPlatform.java (added)
+++ pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTPlatform.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,245 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.scene;
+
+import java.awt.BasicStroke;
+import java.awt.RenderingHints;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.imageio.ImageIO;
+
+import org.apache.pivot.scene.Font;
+import org.apache.pivot.scene.LinearGradientPaint;
+import org.apache.pivot.scene.MultiStopGradientPaint;
+import org.apache.pivot.scene.PathGeometry;
+import org.apache.pivot.scene.Platform;
+import org.apache.pivot.scene.RadialGradientPaint;
+import org.apache.pivot.scene.SolidColorPaint;
+import org.apache.pivot.scene.Stroke;
+import org.apache.pivot.scene.media.Raster;
+
+/**
+ * AWT platform implementation.
+ */
+public class AWTPlatform extends Platform {
+    private static FontRenderContext fontRenderContext;
+
+    static {
+        // Initialize the font render context
+        initializeFontRenderContext();
+
+        // Listen for changes to the font desktop hints property
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        toolkit.addPropertyChangeListener("awt.font.desktophints", new PropertyChangeListener() {
+            @Override
+            public void propertyChange(PropertyChangeEvent event) {
+                initializeFontRenderContext();
+            }
+        });
+    }
+
+    @Override
+    public Font.Metrics getFontMetrics(Font font) {
+        java.awt.Font nativeFont = getNativeFont(font);
+        LineMetrics lm = nativeFont.getLineMetrics("", fontRenderContext);
+
+        return new Font.Metrics(lm.getAscent(), lm.getDescent(), lm.getLeading());
+    }
+
+    @Override
+    public float measureText(Font font, CharSequence text, int start, int length) {
+        java.awt.Font nativeFont = getNativeFont(font);
+        Rectangle2D stringBounds = nativeFont.getStringBounds(new CharSequenceCharacterIterator(text),
+            0, text.length(), fontRenderContext);
+
+        return (int)Math.ceil(stringBounds.getWidth());
+    }
+
+    @Override
+    public Raster readRaster(InputStream inputStream) throws IOException {
+        return new AWTRaster(ImageIO.read(inputStream));
+    }
+
+    @Override
+    public void writeRaster(Raster raster, String mimeType,  OutputStream outputStream)
+        throws IOException {
+        ImageIO.write((BufferedImage)raster.getNativeRaster(), mimeType, outputStream);
+    }
+
+    @Override
+    protected java.awt.Font getNativeFont(Font font) {
+        int style = 0;
+
+        if (font.bold) {
+            style |= java.awt.Font.BOLD;
+        }
+
+        if (font.italic) {
+            style |= java.awt.Font.ITALIC;
+        }
+
+        return new java.awt.Font(font.name, font.size, style);
+    }
+
+    @Override
+    protected java.awt.Color getNativePaint(SolidColorPaint solidColorPaint) {
+        return new java.awt.Color(solidColorPaint.color.red,
+            solidColorPaint.color.green,
+            solidColorPaint.color.blue,
+            solidColorPaint.color.alpha);
+    }
+
+    @Override
+    protected java.awt.LinearGradientPaint getNativePaint(LinearGradientPaint linearGradientPaint) {
+        int n = linearGradientPaint.stops.size();
+        float[] fractions = new float[n];
+        java.awt.Color[] colors = new java.awt.Color[n];
+
+        for (int i = 0; i < n; i++) {
+            MultiStopGradientPaint.Stop stop = linearGradientPaint.stops.get(i);
+            fractions[i] = stop.offset;
+            colors[i] = new java.awt.Color(stop.color.red,
+                stop.color.green,
+                stop.color.blue,
+                stop.color.alpha);
+        }
+
+        return new java.awt.LinearGradientPaint(linearGradientPaint.start.x,
+            linearGradientPaint.start.y,
+            linearGradientPaint.end.x,
+            linearGradientPaint.end.y,
+            fractions, colors);
+    }
+
+    @Override
+    protected java.awt.RadialGradientPaint getNativePaint(RadialGradientPaint radialGradientPaint) {
+        int n = radialGradientPaint.stops.size();
+        float[] fractions = new float[n];
+        java.awt.Color[] colors = new java.awt.Color[n];
+
+        for (int i = 0; i < n; i++) {
+            MultiStopGradientPaint.Stop stop = radialGradientPaint.stops.get(i);
+            fractions[i] = stop.offset;
+            colors[i] = new java.awt.Color(stop.color.red,
+                stop.color.green,
+                stop.color.blue,
+                stop.color.alpha);
+        }
+
+        return new java.awt.RadialGradientPaint(radialGradientPaint.center.x,
+            radialGradientPaint.center.y,
+            radialGradientPaint.radius, fractions, colors);
+    }
+
+    @Override
+    protected BasicStroke getNativeStroke(Stroke stroke) {
+        int cap = -1;
+        switch (stroke.lineCap) {
+            case BUTT: {
+                cap = BasicStroke.CAP_BUTT;
+                break;
+            }
+
+            case ROUND: {
+                cap = BasicStroke.CAP_ROUND;
+                break;
+            }
+
+            case SQUARE: {
+                cap = BasicStroke.CAP_SQUARE;
+                break;
+            }
+        }
+
+        int join = -1;
+        switch (stroke.lineJoin) {
+            case ROUND: {
+                join = BasicStroke.JOIN_ROUND;
+                break;
+            }
+
+            case BEVEL: {
+                join = BasicStroke.JOIN_BEVEL;
+                break;
+            }
+
+            case MITER: {
+                join = BasicStroke.JOIN_MITER;
+                break;
+            }
+        }
+
+        float[] dash = null;
+        float dashPhase = 0f;
+        switch (stroke.lineStyle) {
+            case DASHED: {
+                // TODO
+                break;
+            }
+
+            case DOTTED: {
+                // TODO
+                break;
+            }
+        }
+
+        return new BasicStroke(stroke.lineWidth, cap, join, stroke.miterLimit, dash, dashPhase);
+    }
+
+    @Override
+    protected Path2D.Float getNativePathGeometry(PathGeometry pathGeometry) {
+        // TODO
+        return null;
+    }
+
+    public static FontRenderContext getFontRenderContext() {
+        return fontRenderContext;
+    }
+
+    private static void initializeFontRenderContext() {
+        Object aaHint = null;
+        Object fmHint = null;
+
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        java.util.Map<?, ?> fontDesktopHints =
+            (java.util.Map<?, ?>)toolkit.getDesktopProperty("awt.font.desktophints");
+        if (fontDesktopHints != null) {
+            aaHint = fontDesktopHints.get(RenderingHints.KEY_TEXT_ANTIALIASING);
+            fmHint = fontDesktopHints.get(RenderingHints.KEY_FRACTIONALMETRICS);
+        }
+
+        if (aaHint == null) {
+            aaHint = RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT;
+        }
+
+        if (fmHint == null) {
+            fmHint = RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT;
+        }
+
+        fontRenderContext = new FontRenderContext(null, aaHint, fmHint);
+    }
+}

Added: pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTRaster.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTRaster.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTRaster.java (added)
+++ pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTRaster.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.scene;
+
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+import org.apache.pivot.scene.Color;
+import org.apache.pivot.scene.Graphics;
+import org.apache.pivot.scene.media.Raster;
+
+/**
+ * AWT raster implementation.
+ */
+public class AWTRaster extends Raster {
+    private BufferedImage bufferedImage;
+
+    public AWTRaster(BufferedImage bufferedImage) {
+        if (bufferedImage == null) {
+            throw new IllegalArgumentException();
+        }
+
+        this.bufferedImage = bufferedImage;
+    }
+
+    @Override
+    public int getWidth() {
+        return bufferedImage.getWidth();
+    }
+
+    @Override
+    public int getHeight() {
+        return bufferedImage.getHeight();
+    }
+
+    @Override
+    public Color getPixel(int x, int y) {
+        return new Color(bufferedImage.getRGB(x, y));
+    }
+
+    @Override
+    public void setPixel(int x, int y, Color color) {
+        bufferedImage.setRGB(x, y, color.toInt());
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        Graphics2D graphics2D = (Graphics2D)bufferedImage.getGraphics();
+        graphics2D.clipRect(0, 0, getWidth(), getHeight());
+
+        return new AWTGraphics(graphics2D);
+    }
+
+    @Override
+    public BufferedImage getNativeRaster() {
+        return bufferedImage;
+    }
+}

Added: pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTStageHost.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTStageHost.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTStageHost.java (added)
+++ pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/AWTStageHost.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,603 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.scene;
+
+import java.awt.AWTEvent;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.RenderingHints;
+import java.awt.Toolkit;
+import java.awt.Transparency;
+import java.awt.event.ComponentEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseWheelEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Random;
+
+import org.apache.pivot.scene.Stage;
+
+/**
+ * AWT scene graph host component.
+ */
+public class AWTStageHost extends java.awt.Component {
+    private static final long serialVersionUID = 0;
+
+    private Stage stage = new Stage() {
+        @Override
+        public void invalidate() {
+            AWTStageHost.this.invalidate();
+        }
+
+        @Override
+        public void repaintHost(int x, int y, int width, int height) {
+            AWTStageHost.this.repaint(x, y, width, height);
+        }
+
+        @Override
+        public Graphics getHostGraphics() {
+            Graphics2D graphics2D = (Graphics2D)AWTStageHost.this.getGraphics();
+
+            Graphics graphics = null;
+            if (graphics2D != null) {
+                graphics2D.clipRect(0, 0, getWidth(), getHeight());
+                graphics = new AWTGraphics(graphics2D);
+            }
+
+            return graphics;
+        }
+
+        @Override
+        public void requestNativeFocus() {
+            requestFocusInWindow();
+        }
+
+        @Override
+        public Object getNativeHost() {
+            return AWTStageHost.this;
+        }
+    };
+
+    private Node mouseCapturer = null;
+    private Node focusOwner = null;
+
+    private boolean doubleBuffered = true;
+    private boolean disableVolatileBuffer = true;
+
+    private boolean debugPaint = false;
+    private boolean debugFocus = false;
+
+    private boolean paintPending = false;
+
+    public AWTStageHost() {
+        enableEvents(AWTEvent.COMPONENT_EVENT_MASK
+            | AWTEvent.FOCUS_EVENT_MASK
+            | AWTEvent.MOUSE_EVENT_MASK
+            | AWTEvent.MOUSE_MOTION_EVENT_MASK
+            | AWTEvent.MOUSE_WHEEL_EVENT_MASK
+            | AWTEvent.KEY_EVENT_MASK);
+
+        try {
+            System.setProperty("sun.awt.noerasebackground", "true");
+            System.setProperty("sun.awt.erasebackgroundonresize", "false");
+        } catch (SecurityException exception) {
+            // No-op
+        }
+
+        setFocusTraversalKeysEnabled(false);
+
+        // Listen for changes to the font desktop hints property
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        toolkit.addPropertyChangeListener("awt.font.desktophints", new PropertyChangeListener() {
+            @Override
+            public void propertyChange(PropertyChangeEvent event) {
+                invalidate();
+            }
+        });
+    }
+
+    public Stage getStage() {
+        return stage;
+    }
+
+    @Override
+    public boolean isDoubleBuffered() {
+        return doubleBuffered;
+    }
+
+    public void setDoubleBuffered(boolean doubleBuffered) {
+        this.doubleBuffered = doubleBuffered;
+    }
+
+    public boolean getDisableVolatileBuffer() {
+        return disableVolatileBuffer;
+    }
+
+    public void setDisableVolatileBuffer(boolean disableVolatileBuffer) {
+        this.disableVolatileBuffer = disableVolatileBuffer;
+    }
+
+    public boolean getDebugPaint() {
+        return debugPaint;
+    }
+
+    public void setDebugPaint(boolean debugPaint) {
+        this.debugPaint = debugPaint;
+    }
+
+    public boolean getDebugFocus() {
+        return debugFocus;
+    }
+
+    public void setDebugFocus(boolean debugFocus) {
+        this.debugFocus = debugFocus;
+
+        // TODO
+
+        repaint();
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+        return new Dimension(stage.getPreferredWidth(), stage.getPreferredHeight());
+    }
+
+    @Override
+    public void repaint(int x, int y, int width, int height) {
+        // Ensure that the repaint call is properly bounded (some
+        // implementations of AWT do not properly clip the repaint call
+        // when x or y is negative: the negative value is converted to 0,
+        // but the width/height is not adjusted)
+        if (x < 0) {
+            width = Math.max(width + x, 0);
+            x = 0;
+        }
+
+        if (y < 0) {
+            height = Math.max(height + y, 0);
+            y = 0;
+        }
+
+        if (width > 0
+            && height > 0) {
+            super.repaint(x, y, width, height);
+
+            paintPending = true;
+        }
+    }
+
+    @Override
+    public void paint(java.awt.Graphics graphics) {
+        // Intersect the clip region with the bounds of this component
+        // (for some reason, AWT does not do this automatically)
+        graphics.clipRect(0, 0, getWidth(), getHeight());
+
+        java.awt.Rectangle clipBounds = graphics.getClipBounds();
+        if (clipBounds != null
+            && !clipBounds.isEmpty()) {
+            Graphics2D graphics2D = (Graphics2D)graphics;
+
+            try {
+                if (doubleBuffered) {
+                    if (disableVolatileBuffer
+                        || !paintVolatileBuffered(graphics2D)) {
+                        if (!paintBuffered(graphics2D)) {
+                            paintUnbuffered(graphics2D);
+                        }
+                    }
+                } else {
+                    paintUnbuffered(graphics2D);
+                }
+
+                if (debugPaint) {
+                    Random random = new Random();
+                    graphics.setColor(new java.awt.Color(random.nextInt(256),
+                        random.nextInt(256), random.nextInt(256), 75));
+                    graphics.fillRect(0, 0, getWidth(), getHeight());
+                }
+            } catch (RuntimeException exception) {
+                exception.printStackTrace();
+                throw exception;
+            }
+        }
+
+        paintPending = false;
+    }
+
+    @Override
+    public void update(java.awt.Graphics graphics) {
+        paint(graphics);
+    }
+
+    /**
+     * Attempts to paint the stage using an offscreen buffer.
+     *
+     * @param graphics
+     * The source graphics context.
+     *
+     * @return
+     * <tt>true</tt> if the stage was painted using the offscreen
+     * buffer; <tt>false</tt>, otherwise.
+     */
+    private boolean paintBuffered(Graphics2D graphics) {
+        boolean painted = false;
+
+        // Paint the stage into an offscreen buffer
+        GraphicsConfiguration gc = graphics.getDeviceConfiguration();
+        java.awt.Rectangle clipBounds = graphics.getClipBounds();
+        java.awt.image.BufferedImage bufferedImage =
+            gc.createCompatibleImage(clipBounds.width, clipBounds.height, Transparency.OPAQUE);
+
+        if (bufferedImage != null) {
+            Graphics2D bufferedImageGraphics = (Graphics2D)bufferedImage.getGraphics();
+            bufferedImageGraphics.setClip(0, 0, clipBounds.width, clipBounds.height);
+            bufferedImageGraphics.translate(-clipBounds.x, -clipBounds.y);
+
+            try {
+                paintUnbuffered(bufferedImageGraphics);
+                graphics.drawImage(bufferedImage, clipBounds.x, clipBounds.y, this);
+            } finally {
+                bufferedImageGraphics.dispose();
+            }
+
+            painted = true;
+        }
+
+        return painted;
+    }
+
+    /**
+     * Attempts to paint the stage using a volatile offscreen buffer.
+     *
+     * @param graphics
+     * The source graphics context.
+     *
+     * @return
+     * <tt>true</tt> if the stage was painted using the offscreen
+     * buffer; <tt>false</tt>, otherwise.
+     */
+    private boolean paintVolatileBuffered(Graphics2D graphics) {
+        boolean painted = false;
+
+        // Paint the stage into a volatile offscreen buffer
+        GraphicsConfiguration gc = graphics.getDeviceConfiguration();
+        java.awt.Rectangle clipBounds = graphics.getClipBounds();
+        java.awt.image.VolatileImage volatileImage =
+            gc.createCompatibleVolatileImage(clipBounds.width, clipBounds.height,
+                Transparency.OPAQUE);
+
+        if (volatileImage != null) {
+            int valid = volatileImage.validate(gc);
+
+            if (valid == java.awt.image.VolatileImage.IMAGE_OK
+                || valid == java.awt.image.VolatileImage.IMAGE_RESTORED) {
+                Graphics2D volatileImageGraphics = volatileImage.createGraphics();
+                volatileImageGraphics.setClip(0, 0, clipBounds.width, clipBounds.height);
+                volatileImageGraphics.translate(-clipBounds.x, -clipBounds.y);
+
+                try {
+                    paintUnbuffered(volatileImageGraphics);
+                    graphics.drawImage(volatileImage, clipBounds.x, clipBounds.y, this);
+                } finally {
+                    volatileImageGraphics.dispose();
+                }
+
+                painted = !volatileImage.contentsLost();
+            }
+        }
+
+        return painted;
+    }
+
+    /**
+     * Paints the stage without any buffering.
+     *
+     * @param graphics
+     */
+    private void paintUnbuffered(Graphics2D graphics) {
+        graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
+
+        AWTGraphics awtGraphics = new AWTGraphics(graphics);
+        stage.paint(awtGraphics);
+    }
+
+    @Override
+    protected void processComponentEvent(ComponentEvent event) {
+        super.processComponentEvent(event);
+
+        switch (event.getID()) {
+            case ComponentEvent.COMPONENT_RESIZED: {
+                stage.setSize(Math.max(getWidth(), 0), Math.max(getHeight(), 0));
+                break;
+            }
+        }
+    }
+
+    @Override
+    protected void processFocusEvent(FocusEvent event) {
+        super.processFocusEvent(event);
+
+        switch(event.getID()) {
+            case FocusEvent.FOCUS_GAINED: {
+                if (focusOwner != null
+                    && focusOwner.isShowing()
+                    && !focusOwner.isBlocked()) {
+                    focusOwner.requestFocus();
+                }
+
+                focusOwner = null;
+
+                break;
+            }
+
+            case FocusEvent.FOCUS_LOST: {
+                focusOwner = Node.getFocusedNode();
+                Node.clearFocus();
+
+                break;
+            }
+        }
+    }
+
+    @Override
+    protected void processMouseEvent(MouseEvent event) {
+        super.processMouseEvent(event);
+
+        int x = event.getX();
+        int y = event.getY();
+
+        // Set the mouse button state
+        int mouseButtons = 0x00;
+
+        int modifiersEx = event.getModifiersEx();
+        if ((modifiersEx & MouseEvent.BUTTON1_DOWN_MASK) > 0) {
+            mouseButtons |= Mouse.Button.LEFT.getMask();
+        }
+
+        if ((modifiersEx & MouseEvent.BUTTON2_DOWN_MASK) > 0) {
+            mouseButtons |= Mouse.Button.MIDDLE.getMask();
+        }
+
+        if ((modifiersEx & MouseEvent.BUTTON3_DOWN_MASK) > 0) {
+            mouseButtons |= Mouse.Button.RIGHT.getMask();
+        }
+
+        Mouse.setButtons(mouseButtons);
+
+        // Get the button associated with this event
+        Mouse.Button button = null;
+        switch (event.getButton()) {
+            case MouseEvent.BUTTON1: {
+                button = Mouse.Button.LEFT;
+                break;
+            }
+
+            case MouseEvent.BUTTON2: {
+                button = Mouse.Button.MIDDLE;
+                break;
+            }
+
+            case MouseEvent.BUTTON3: {
+                button = Mouse.Button.RIGHT;
+                break;
+            }
+        }
+
+        // Process the event
+        boolean consumed = false;
+        try {
+            switch(event.getID()) {
+                case MouseEvent.MOUSE_ENTERED: {
+                    stage.mouseEntered();
+                    break;
+                }
+
+                case MouseEvent.MOUSE_EXITED: {
+                    stage.mouseExited();
+                    break;
+                }
+
+                case MouseEvent.MOUSE_PRESSED: {
+                    consumed = stage.mousePressed(button, x, y);
+                    break;
+                }
+
+                case MouseEvent.MOUSE_RELEASED: {
+                    consumed = stage.mouseReleased(button, x, y);
+                    break;
+                }
+            }
+        } catch (Exception exception) {
+            exception.printStackTrace();
+        }
+
+        if (consumed) {
+            event.consume();
+        }
+    }
+
+    @Override
+    protected void processMouseMotionEvent(MouseEvent event) {
+        super.processMouseMotionEvent(event);
+
+        if (!paintPending) {
+            int x = event.getX();
+            int y = event.getY();
+
+            // Process the event
+            boolean consumed = false;
+            try {
+                switch (event.getID()) {
+                    case MouseEvent.MOUSE_MOVED: {
+                        mouseCapturer = null;
+
+                        consumed = stage.mouseMoved(x, y, false);
+                        break;
+                    }
+
+                    case MouseEvent.MOUSE_DRAGGED: {
+                        if (mouseCapturer == null) {
+                            mouseCapturer = stage.getDescendantAt(x, y);
+                        }
+
+                        Point location = mouseCapturer.mapPointFromAncestor(stage, x, y);
+                        consumed = mouseCapturer.mouseMoved(location.x, location.y, true);
+                        break;
+                    }
+                }
+            } catch (Exception exception) {
+                exception.printStackTrace();
+            }
+
+            if (consumed) {
+                event.consume();
+            }
+        }
+    }
+
+    @Override
+    protected void processMouseWheelEvent(MouseWheelEvent event) {
+        super.processMouseWheelEvent(event);
+
+        // Get the event coordinates
+        int x = event.getX();
+        int y = event.getY();
+
+        // Get the scroll type
+        Mouse.ScrollType scrollType = null;
+        switch (event.getScrollType()) {
+            case MouseWheelEvent.WHEEL_BLOCK_SCROLL: {
+                scrollType = Mouse.ScrollType.BLOCK;
+                break;
+            }
+
+            case MouseWheelEvent.WHEEL_UNIT_SCROLL: {
+                scrollType = Mouse.ScrollType.UNIT;
+                break;
+            }
+        }
+
+        // Process the event
+        boolean consumed = false;
+        try {
+            switch (event.getID()) {
+                case MouseEvent.MOUSE_WHEEL: {
+                    consumed = stage.mouseWheelScrolled(scrollType, event.getScrollAmount(),
+                        event.getWheelRotation(), x, y);
+                    break;
+                }
+            }
+        } catch (Exception exception) {
+            exception.printStackTrace();
+        }
+
+        if (consumed) {
+            event.consume();
+        }
+    }
+
+    @Override
+    protected void processKeyEvent(KeyEvent event) {
+        super.processKeyEvent(event);
+
+        if (focusOwner != null
+            && !focusOwner.isBlocked()) {
+            int modifiersEx = event.getModifiersEx();
+            int awtKeyLocation = event.getKeyLocation();
+
+            // Set the keyboard modifier state
+            int keyboardModifiers = 0;
+            if ((modifiersEx & KeyEvent.SHIFT_DOWN_MASK) > 0) {
+                keyboardModifiers |= Keyboard.Modifier.SHIFT.getMask();
+            }
+
+            // Ignore Control when Alt-Graphics is pressed
+            if ((modifiersEx & KeyEvent.CTRL_DOWN_MASK) > 0
+                && ((modifiersEx & KeyEvent.ALT_DOWN_MASK) == 0
+                    || awtKeyLocation == KeyEvent.KEY_LOCATION_RIGHT)) {
+                keyboardModifiers |= Keyboard.Modifier.CTRL.getMask();
+            }
+
+            if ((modifiersEx & KeyEvent.ALT_DOWN_MASK) > 0) {
+                keyboardModifiers |= Keyboard.Modifier.ALT.getMask();
+            }
+
+            if ((modifiersEx & KeyEvent.META_DOWN_MASK) > 0) {
+                keyboardModifiers |= Keyboard.Modifier.META.getMask();
+            }
+
+            Keyboard.setModifiers(keyboardModifiers);
+
+            // Get the key location
+            Keyboard.KeyLocation keyLocation = null;
+            switch (awtKeyLocation) {
+                case KeyEvent.KEY_LOCATION_STANDARD: {
+                    keyLocation = Keyboard.KeyLocation.STANDARD;
+                    break;
+                }
+
+                case KeyEvent.KEY_LOCATION_LEFT: {
+                    keyLocation = Keyboard.KeyLocation.LEFT;
+                    break;
+                }
+
+                case KeyEvent.KEY_LOCATION_RIGHT: {
+                    keyLocation = Keyboard.KeyLocation.RIGHT;
+                    break;
+                }
+
+                case KeyEvent.KEY_LOCATION_NUMPAD: {
+                    keyLocation = Keyboard.KeyLocation.KEYPAD;
+                    break;
+                }
+            }
+
+            // Process the event
+            boolean consumed = false;
+            try {
+                switch (event.getID()) {
+                    case KeyEvent.KEY_PRESSED: {
+                        int keyCode = event.getKeyCode();
+                        consumed = focusOwner.keyPressed(keyCode, keyLocation);
+                        break;
+                    }
+
+                    case KeyEvent.KEY_RELEASED: {
+                        int keyCode = event.getKeyCode();
+                        consumed = focusOwner.keyReleased(keyCode, keyLocation);
+                        break;
+                    }
+
+                    case KeyEvent.KEY_TYPED: {
+                        char keyChar = event.getKeyChar();
+                        consumed = focusOwner.keyTyped(keyChar);
+                        break;
+                    }
+                }
+            } catch (Exception exception) {
+                exception.printStackTrace();
+            }
+
+            if (consumed) {
+                event.consume();
+            }
+        }
+    }
+}

Added: pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/CharSequenceCharacterIterator.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/CharSequenceCharacterIterator.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/CharSequenceCharacterIterator.java (added)
+++ pivot/branches/3.x/scene-platform-awt/src/org/apache/pivot/scene/CharSequenceCharacterIterator.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.scene;
+
+import java.text.CharacterIterator;
+
+/**
+ * Character iterator that is backed by a {@link java.lang.CharSequence}.
+ */
+public class CharSequenceCharacterIterator implements CharacterIterator {
+    private CharSequence charSequence;
+    private int beginIndex;
+    private int endIndex;
+
+    private int index = -1;
+
+    public CharSequenceCharacterIterator(CharSequence charSequence) {
+        this(charSequence, 0);
+    }
+
+    public CharSequenceCharacterIterator(CharSequence charSequence, int beginIndex) {
+        this(charSequence, beginIndex, -1);
+    }
+
+    public CharSequenceCharacterIterator(CharSequence charSequence, int beginIndex, int endIndex) {
+        this(charSequence, beginIndex, endIndex, beginIndex);
+    }
+
+    public CharSequenceCharacterIterator(CharSequence charSequence, int beginIndex, int endIndex, int index) {
+        if (charSequence == null) {
+            throw new IllegalArgumentException();
+        }
+
+        if (endIndex == -1) {
+            endIndex = charSequence.length();
+        }
+
+        if (beginIndex > endIndex) {
+            throw new IllegalArgumentException();
+        }
+
+        if (beginIndex < 0
+            || endIndex > charSequence.length()) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        if (index < beginIndex
+            || index > endIndex) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        this.charSequence = charSequence;
+        this.beginIndex = beginIndex;
+        this.endIndex = endIndex;
+
+        setIndex(index);
+    }
+
+    @Override
+    public char first() {
+        return setIndex(beginIndex);
+    }
+
+    @Override
+    public char last() {
+        return setIndex(charSequence.length() == 0 ? endIndex : endIndex - 1);
+    }
+
+    @Override
+    public char next() {
+        return setIndex(index < endIndex ? index + 1 : DONE);
+    }
+
+    @Override
+    public char previous() {
+        return setIndex(index > beginIndex ? index - 1 : DONE);
+    }
+
+    @Override
+    public char current() {
+        return (index < endIndex) ? charSequence.charAt(index) : DONE;
+    }
+
+    @Override
+    public int getBeginIndex() {
+        return beginIndex;
+    }
+
+    @Override
+    public int getEndIndex() {
+        return endIndex;
+    }
+
+    @Override
+    public int getIndex() {
+        return index;
+    }
+
+    @Override
+    public char setIndex(int index) {
+        if (index < beginIndex
+            || index > endIndex) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        this.index = index;
+
+        return current();
+    }
+
+    @Override
+    public Object clone() {
+        return new CharSequenceCharacterIterator(charSequence, beginIndex, endIndex, index);
+    }
+}

Added: pivot/branches/3.x/scene-platform-swt/.classpath
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-swt/.classpath?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-swt/.classpath (added)
+++ pivot/branches/3.x/scene-platform-swt/.classpath Tue Jan 11 13:40:20 2011
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/core"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/scene"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/SWT"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: pivot/branches/3.x/scene-platform-swt/.project
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-swt/.project?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-swt/.project (added)
+++ pivot/branches/3.x/scene-platform-swt/.project Tue Jan 11 13:40:20 2011
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>scene-platform-swt</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTGraphics.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTGraphics.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTGraphics.java (added)
+++ pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTGraphics.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.scene;
+
+public class SWTGraphics {
+    // TODO
+}

Added: pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTPlatform.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTPlatform.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTPlatform.java (added)
+++ pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTPlatform.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.scene;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.pivot.scene.Font;
+import org.apache.pivot.scene.LinearGradientPaint;
+import org.apache.pivot.scene.PathGeometry;
+import org.apache.pivot.scene.Platform;
+import org.apache.pivot.scene.RadialGradientPaint;
+import org.apache.pivot.scene.SolidColorPaint;
+import org.apache.pivot.scene.Stroke;
+import org.apache.pivot.scene.media.Raster;
+import org.eclipse.swt.graphics.Pattern;
+
+/**
+ * AWT platform implementation.
+ */
+public class SWTPlatform extends Platform {
+    @Override
+    public Font.Metrics getFontMetrics(Font font) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public float measureText(Font font, CharSequence text, int start, int length) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public Raster readRaster(InputStream inputStream) throws IOException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void writeRaster(Raster raster, String mimeType,  OutputStream outputStream)
+        throws IOException {
+    }
+
+    @Override
+    protected org.eclipse.swt.graphics.Font getNativeFont(Font font) {
+        // TODO Return a FontReference; this will be a wrapper class that
+        // contains both a reference to the Font itself as well as the
+        // native font instance. In the FontReference finalizer(), we'll
+        // remove the entry from the reference-counted map and dispose
+        // the native font, if necessary. We'll also dispose() all
+        // undisposed resources when the stage host component is disposed.
+
+        return null;
+    }
+
+    @Override
+    protected org.eclipse.swt.graphics.Color getNativePaint(SolidColorPaint solidColorPaint) {
+        // TODO Return a ColorReference
+        return null;
+    }
+
+    @Override
+    protected Pattern getNativePaint(LinearGradientPaint linearGradientPaint) {
+        // TODO Return a PatternReference
+        return null;
+    }
+
+    @Override
+    protected Pattern getNativePaint(RadialGradientPaint radialGradientPaint) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected Object getNativeStroke(Stroke stroke) {
+        return null;
+    }
+
+    @Override
+    protected Object getNativePathGeometry(PathGeometry pathGeometry) {
+        // TODO
+        return null;
+    }
+}

Added: pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTRaster.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTRaster.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTRaster.java (added)
+++ pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTRaster.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.scene;
+
+import org.apache.pivot.scene.Color;
+import org.apache.pivot.scene.Graphics;
+import org.apache.pivot.scene.media.Raster;
+
+/**
+ * SWT raster implementation.
+ */
+public class SWTRaster extends Raster {
+    @Override
+    public int getWidth() {
+        // TODO
+        return 0;
+    }
+
+    @Override
+    public int getHeight() {
+        // TODO
+        return 0;
+    }
+
+    @Override
+    public Color getPixel(int x, int y) {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public void setPixel(int x, int y, Color color) {
+        // TODO
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        // TODO
+        return null;
+    }
+
+    @Override
+    // TODO Return typed value
+    public Object getNativeRaster() {
+        // TODO
+        return null;
+    }
+}

Added: pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTStageHost.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTStageHost.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTStageHost.java (added)
+++ pivot/branches/3.x/scene-platform-swt/src/org/apache/pivot/scene/SWTStageHost.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.scene;
+
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+
+public class SWTStageHost extends Canvas {
+    public SWTStageHost(Composite parent, int style) {
+        super(parent, style);
+
+        // TODO Use appropriate styles to control redraws
+
+        // TODO Add a paint listener
+    }
+
+    // TODO We'll need to maintain a reference-counted cache of resources
+    // such as fonts and paints. We'll need to dispose that cache when the
+    // stage host is disposed. Maybe we can use weak references to manage
+    // this. We could use a weak map of org.apache.pivot.scene.Font to
+    // org.eclipse.swt.graphics.Font, etc. When the gargbage collector
+    // detects that no more references to a given Font are outstanding,
+    // the association will be removed from the map and we will dispose
+    // the resource.
+}

Added: pivot/branches/3.x/ui-platform-awt/.classpath
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/ui-platform-awt/.classpath?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/ui-platform-awt/.classpath (added)
+++ pivot/branches/3.x/ui-platform-awt/.classpath Tue Jan 11 13:40:20 2011
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/core"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/scene"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/ui"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/scene-platform-awt"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: pivot/branches/3.x/ui-platform-awt/.project
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/ui-platform-awt/.project?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/ui-platform-awt/.project (added)
+++ pivot/branches/3.x/ui-platform-awt/.project Tue Jan 11 13:40:20 2011
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ui-platform-awt</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/BrowserApplicationContext.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/BrowserApplicationContext.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/BrowserApplicationContext.java (added)
+++ pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/BrowserApplicationContext.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.ui;
+
+import java.applet.Applet;
+import java.awt.EventQueue;
+import java.awt.Graphics;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.Locale;
+
+import org.apache.pivot.scene.AWTStageHost;
+
+/**
+ * Applet used to host applications in a web browser.
+ * <p>
+ * This applet supports the following parameters:
+ * <ul>
+ * <li><tt>application_class_name</tt> - the class name of the application to launch.</li>
+ * <li><tt>startup_properties</tt> - startup properties to be passed to the application.
+ * Properties use HTTP query string syntax; e.g. "a=1&b=2".</li>
+ * <li><tt>system_properties</tt> - system properties to set at startup. Properties use HTTP
+ * query string syntax; e.g. "a=1&b=2" (trusted applets only).</li>
+ * </ul>
+ */
+public class BrowserApplicationContext extends Applet {
+    private static final long serialVersionUID = 0;
+
+    private Application application = null;
+
+    public static final String APPLICATION_CLASS_NAME_PARAMETER = "application_class_name";
+    public static final String STARTUP_PROPERTIES_PARAMETER = "startup_properties";
+    public static final String SYSTEM_PROPERTIES_PARAMETER = "system_properties";
+
+    @Override
+    public void init() {
+        // Load the application
+        String applicationClassName = getParameter(APPLICATION_CLASS_NAME_PARAMETER);
+
+        if (applicationClassName == null) {
+            System.err.println(APPLICATION_CLASS_NAME_PARAMETER + " parameter is required.");
+        } else {
+            try {
+                Class<?> applicationClass = Class.forName(applicationClassName);
+                application = (Application)applicationClass.newInstance();
+            } catch (Throwable throwable) {
+                throw new RuntimeException(throwable);
+            }
+        }
+
+        // Load properties specified in the startup properties parameter
+        final HashMap<String, String> startupProperties = new HashMap<String, String>();
+
+        String startupPropertiesParameter = getParameter(STARTUP_PROPERTIES_PARAMETER);
+        if (startupPropertiesParameter != null) {
+            String[] arguments = startupPropertiesParameter.split("&");
+
+            for (int i = 0, n = arguments.length; i < n; i++) {
+                String argument = arguments[i];
+                String[] property = argument.split("=");
+
+                if (property.length == 2) {
+                    String key = property[0].trim();
+                    String value;
+                    try {
+                        value = URLDecoder.decode(property[1].trim(), "UTF-8");
+                    } catch (UnsupportedEncodingException exception) {
+                        throw new RuntimeException(exception);
+                    }
+                    startupProperties.put(key, value);
+                } else {
+                    System.err.println(argument + " is not a valid startup property.");
+                }
+            }
+        }
+
+        // Load properties specified in the system properties parameter
+        String systemPropertiesParameter = getParameter(SYSTEM_PROPERTIES_PARAMETER);
+        if (systemPropertiesParameter != null) {
+            String[] arguments = systemPropertiesParameter.split("&");
+
+            String language = null;
+            String region = null;
+
+            for (int i = 0, n = arguments.length; i < n; i++) {
+                String argument = arguments[i];
+                String[] property = argument.split("=");
+
+                if (property.length == 2) {
+                    String key = property[0].trim();
+                    String value;
+                    try {
+                        value = URLDecoder.decode(property[1].trim(), "UTF-8");
+                    } catch (UnsupportedEncodingException exception) {
+                        throw new RuntimeException(exception);
+                    }
+
+                    if (key.equals("user.language")) {
+                        language = value;
+                    } else if (key.equals("user.region")) {
+                        region = value;
+                    } else {
+                        System.setProperty(key, value);
+                    }
+                } else {
+                    System.err.println(argument + " is not a valid system property.");
+                }
+            }
+
+            if (language != null) {
+                Locale.setDefault((region == null) ? new Locale(language) : new Locale(language, region));
+            }
+        }
+
+        // Add stage host to applet
+        final AWTStageHost awtStageHost = new AWTStageHost();
+        awtStageHost.getStage().setLayout(new StageLayout());
+        setLayout(new java.awt.BorderLayout());
+        add(awtStageHost);
+
+        // Set applet properties
+        setFocusTraversalKeysEnabled(false);
+        setBackground(null);
+
+        // Start up the application
+        Runnable startupCallback = new Runnable() {
+            @Override
+            public void run() {
+                if (application != null) {
+                    try {
+                        application.startup(awtStageHost.getStage(), startupProperties);
+                    } catch (Exception exception) {
+                        exception.printStackTrace();
+                    }
+                }
+            }
+        };
+
+        if (java.awt.EventQueue.isDispatchThread()) {
+            startupCallback.run();
+        } else {
+            try {
+                EventQueue.invokeAndWait(startupCallback);
+            } catch (InterruptedException exception) {
+                throw new RuntimeException(exception);
+            } catch (InvocationTargetException exception) {
+                throw new RuntimeException(exception);
+            }
+        }
+    }
+
+    @Override
+    public void destroy() {
+        // Shut down the application
+        Runnable shutdownCallback = new Runnable() {
+            @Override
+            public void run() {
+                if (application != null) {
+                    try {
+                        application.shutdown(false);
+                    } catch (Exception exception) {
+                        exception.printStackTrace();
+                    }
+
+                    application = null;
+                }
+            }
+        };
+
+        if (java.awt.EventQueue.isDispatchThread()) {
+            shutdownCallback.run();
+        } else {
+            try {
+                EventQueue.invokeAndWait(shutdownCallback);
+            } catch (InterruptedException exception) {
+                throw new RuntimeException(exception);
+            } catch (InvocationTargetException exception) {
+                throw new RuntimeException(exception);
+            }
+        }
+    }
+
+    @Override
+    public void update(Graphics graphics) {
+        paint(graphics);
+    }
+}

Added: pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/DesktopApplicationContext.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/DesktopApplicationContext.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/DesktopApplicationContext.java (added)
+++ pivot/branches/3.x/ui-platform-awt/src/org/apache/pivot/ui/DesktopApplicationContext.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,303 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.ui;
+
+import java.awt.Graphics;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+import org.apache.pivot.scene.AWTStageHost;
+import org.apache.pivot.scene.media.Image;
+
+/**
+ * Application context used to execute applications in a native frame window.
+ */
+public class DesktopApplicationContext {
+    private static Application application = null;
+
+    private static java.awt.Frame hostFrame = new java.awt.Frame() {
+        private static final long serialVersionUID = 0;
+
+        @Override
+        public void update(Graphics graphics) {
+            paint(graphics);
+        }
+    };
+
+    public static final String X_ARGUMENT = "x";
+    public static final String Y_ARGUMENT = "y";
+    public static final String WIDTH_ARGUMENT = "width";
+    public static final String HEIGHT_ARGUMENT = "height";
+    public static final String CENTER_ARGUMENT = "center";
+    public static final String MAXIMIZED_ARGUMENT = "maximized";
+    public static final String RESIZABLE_ARGUMENT = "resizable";
+    public static final String UNDECORATED_ARGUMENT = "undecorated";
+
+    private static final String INVALID_PROPERTY_FORMAT_MESSAGE = "\"%s\" is not a valid startup "
+        + "property (expected format is \"--name=value\").";
+    private static final String INVALID_PROPERTY_VALUE_MESSAGE = "\"%s\" is not a valid value for "
+        + "startup property \"%s\".";
+
+    public static Application getApplication() {
+        return application;
+    }
+
+    public static java.awt.Frame getHostFrame() {
+        return hostFrame;
+    }
+
+    /**
+     * Primary aplication entry point.
+     *
+     * @param args
+     */
+    public static void main(String[] args) {
+        // Load the application
+        if (args.length == 0) {
+            System.err.println("Application class name is required.");
+            return;
+        }
+
+        String applicationClassName = args[0];
+
+        try {
+            Class<?> applicationClass = Class.forName(applicationClassName);
+            application = (Application)applicationClass.newInstance();
+        } catch (Throwable throwable) {
+            throw new RuntimeException(throwable);
+        }
+
+        // Get the startup properties
+        HashMap<String, String> properties = new HashMap<String, String>();
+
+        int x = 0;
+        int y = 0;
+        int width = 800;
+        int height = 600;
+        boolean center = false;
+        boolean maximized = false;
+        boolean resizable = true;
+        boolean undecorated = false;
+
+        try {
+            Preferences preferences = Preferences.userNodeForPackage(DesktopApplicationContext.class);
+            preferences = preferences.node(applicationClassName);
+
+            x = preferences.getInt(X_ARGUMENT, x);
+            y = preferences.getInt(Y_ARGUMENT, y);
+            width = preferences.getInt(WIDTH_ARGUMENT, width);
+            height = preferences.getInt(HEIGHT_ARGUMENT, height);
+            maximized = preferences.getBoolean(MAXIMIZED_ARGUMENT, maximized);
+
+            // Update positioning if window is off-screen
+            GraphicsDevice[] screenDevices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
+            if (screenDevices.length == 1) {
+                if (x < 0) {
+                    x = 0;
+                }
+
+                if (y < 0) {
+                    y = 0;
+                }
+            }
+        } catch (SecurityException exception) {
+            System.err.println("Unable to retrieve startup preferences: " + exception);
+        }
+
+        for (int i = 1, n = args.length; i < n; i++) {
+            String arg = args[i];
+
+            if (arg.startsWith("--")) {
+                arg = arg.substring(2);
+                String[] property = arg.split("=");
+
+                if (property.length == 2) {
+                    String key = property[0];
+                    String value = property[1];
+
+                    try {
+                        if (key.equals(X_ARGUMENT)) {
+                            x = Integer.parseInt(value);
+                        } else if (key.equals(Y_ARGUMENT)) {
+                            y = Integer.parseInt(value);
+                        } else if (key.equals(WIDTH_ARGUMENT)) {
+                            width = Integer.parseInt(value);
+                        } else if (key.equals(HEIGHT_ARGUMENT)) {
+                            height = Integer.parseInt(value);
+                        } else if (key.equals(CENTER_ARGUMENT)) {
+                            center = Boolean.parseBoolean(value);
+                        } else if (key.equals(MAXIMIZED_ARGUMENT)) {
+                            maximized = Boolean.parseBoolean(value);
+                        } else if (key.equals(RESIZABLE_ARGUMENT)) {
+                            resizable = Boolean.parseBoolean(value);
+                        } else if (key.equals(UNDECORATED_ARGUMENT)) {
+                            undecorated = Boolean.parseBoolean(value);
+                        } else {
+                            properties.put(key, value);
+                        }
+                    } catch (Exception exception) {
+                        System.err.println(String.format(INVALID_PROPERTY_VALUE_MESSAGE, value, key));
+                    }
+                } else {
+                    System.err.println(String.format(INVALID_PROPERTY_FORMAT_MESSAGE, arg));
+                }
+            } else {
+                System.err.println(String.format(INVALID_PROPERTY_FORMAT_MESSAGE, arg));
+            }
+        }
+
+        // Add stage host to host frame
+        AWTStageHost awtStageHost = new AWTStageHost();
+        awtStageHost.getStage().setLayout(new StageLayout());
+        hostFrame.add(awtStageHost);
+
+        // Add host frame listeners
+        hostFrame.addWindowListener(new WindowAdapter() {
+            @Override
+            public void windowOpened(WindowEvent event) {
+                event.getWindow().requestFocus();
+            }
+
+            @Override
+            public void windowClosing(WindowEvent arg0) {
+                exit();
+            }
+
+            @Override
+            public void windowClosed(WindowEvent arg0) {
+                System.exit(0);
+            }
+
+            @Override
+            public void windowIconified(WindowEvent arg0) {
+                try {
+                    application.suspend();
+                } catch(Exception exception) {
+                    exception.printStackTrace();
+                }
+            }
+
+            @Override
+            public void windowDeiconified(WindowEvent arg0) {
+                try {
+                    application.resume();
+                } catch(Exception exception) {
+                    exception.printStackTrace();
+                }
+            }
+        });
+
+        // Set the host frame properties
+        hostFrame.setTitle(application.getTitle());
+
+        List<Image> icons = application.getIcons();
+        if (icons != null) {
+            ArrayList<java.awt.Image> iconImages = new ArrayList<java.awt.Image>(icons.size());
+            for (Image image : icons) {
+                iconImages.add((BufferedImage)image.getRaster().getNativeRaster());
+            }
+
+            hostFrame.setIconImages(iconImages);
+        } else {
+            hostFrame.setIconImages(null);
+        }
+
+        hostFrame.setFocusTraversalKeysEnabled(false);
+        hostFrame.setBackground(null);
+
+        hostFrame.setSize(width, height);
+
+        if (center) {
+            java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
+            hostFrame.setLocation((screenSize.width - width) / 2,
+                (screenSize.height - height) / 2);
+        } else {
+            hostFrame.setLocation(x, y);
+        }
+
+        if (maximized) {
+            hostFrame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
+        }
+
+        hostFrame.setResizable(resizable);
+        hostFrame.setUndecorated(undecorated);
+
+        // Show the host frame
+        hostFrame.setVisible(true);
+
+        // Start up the application
+        try {
+            application.startup(awtStageHost.getStage(), properties);
+        } catch (Exception exception) {
+            exception.printStackTrace();
+        }
+    }
+
+    /**
+     * Terminates the application context.
+     */
+    public static boolean exit() {
+        boolean cancelShutdown = false;
+
+        if (application != null) {
+            // Shut down the application
+            try {
+                cancelShutdown = application.shutdown(true);
+            } catch(Exception exception) {
+                exception.printStackTrace();
+            }
+
+            if (!cancelShutdown) {
+                try {
+                    Preferences preferences = Preferences.userNodeForPackage(DesktopApplicationContext.class);
+                    preferences = preferences.node(application.getClass().getName());
+
+                    boolean maximized = (hostFrame.getExtendedState()
+                        & java.awt.Frame.MAXIMIZED_BOTH) == java.awt.Frame.MAXIMIZED_BOTH;
+                    if (!maximized) {
+                        preferences.putInt(X_ARGUMENT, hostFrame.getX());
+                        preferences.putInt(Y_ARGUMENT, hostFrame.getY());
+                        preferences.putInt(WIDTH_ARGUMENT, hostFrame.getWidth());
+                        preferences.putInt(HEIGHT_ARGUMENT, hostFrame.getHeight());
+                    }
+
+                    preferences.putBoolean(MAXIMIZED_ARGUMENT, maximized);
+
+                    preferences.flush();
+                } catch (SecurityException exception) {
+                    // No-op
+                } catch (BackingStoreException exception) {
+                    // No-op
+                }
+            }
+        }
+
+        if (!cancelShutdown) {
+            hostFrame.dispose();
+        }
+
+        return cancelShutdown;
+    }
+}

Added: pivot/branches/3.x/ui-platform-swt/.classpath
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/ui-platform-swt/.classpath?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/ui-platform-swt/.classpath (added)
+++ pivot/branches/3.x/ui-platform-swt/.classpath Tue Jan 11 13:40:20 2011
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/core"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/scene"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/ui"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/scene-platform-swt"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/SWT"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: pivot/branches/3.x/ui-platform-swt/.project
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/ui-platform-swt/.project?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/ui-platform-swt/.project (added)
+++ pivot/branches/3.x/ui-platform-swt/.project Tue Jan 11 13:40:20 2011
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ui-platform-swt</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/DesktopApplicationContext.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/DesktopApplicationContext.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/DesktopApplicationContext.java (added)
+++ pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/DesktopApplicationContext.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,5 @@
+package org.apache.pivot.ui;
+
+public class DesktopApplicationContext {
+
+}

Added: pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/PluginApplicationContext.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/PluginApplicationContext.java?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/PluginApplicationContext.java (added)
+++ pivot/branches/3.x/ui-platform-swt/src/org/apache/pivot/ui/PluginApplicationContext.java Tue Jan 11 13:40:20 2011
@@ -0,0 +1,5 @@
+package org.apache.pivot.ui;
+
+public class PluginApplicationContext {
+
+}

Added: pivot/branches/3.x/ui-skin-terra/.classpath
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/ui-skin-terra/.classpath?rev=1057619&view=auto
==============================================================================
--- pivot/branches/3.x/ui-skin-terra/.classpath (added)
+++ pivot/branches/3.x/ui-skin-terra/.classpath Tue Jan 11 13:40:20 2011
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>