diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
new file mode 100644
index 0000000..5ff8362
--- /dev/null
+++ b/samplecode/SampleApp.cpp
@@ -0,0 +1,563 @@
+#include "SkCanvas.h"
+#include "SkDevice.h"
+#include "SkGLCanvas.h"
+#include "SkGraphics.h"
+#include "SkPaint.h"
+#include "SkPicture.h"
+#include "SkStream.h"
+#include "SkWindow.h"
+
+#include "SampleCode.h"
+
+#include <AGL/agl.h>
+#include <OpenGL/gl.h>
+
+#define ANIMATING_EVENTTYPE "nextSample"
+#define ANIMATING_DELAY     750
+
+#define USE_OFFSCREEN
+
+SkViewRegister* SkViewRegister::gHead;
+SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
+    static bool gOnce;
+    if (!gOnce) {
+        gHead = NULL;
+        gOnce = true;
+    }
+    
+    fChain = gHead;
+    gHead = this;
+}
+
+static AGLContext   gAGLContext;
+
+static void init_gl(WindowRef wref) {
+    GLint major, minor;
+    
+    aglGetVersion(&major, &minor);
+    SkDebugf("---- agl version %d %d\n", major, minor);
+    
+    const GLint pixelAttrs[] = {
+        AGL_RGBA,
+        AGL_DEPTH_SIZE, 32,
+        AGL_OFFSCREEN,
+        AGL_NONE
+    };
+    
+    AGLPixelFormat format = aglCreatePixelFormat(pixelAttrs);
+    SkDebugf("----- agl format %p\n", format);
+    gAGLContext = aglCreateContext(format, NULL);
+    SkDebugf("----- agl context %p\n", gAGLContext);
+    aglDestroyPixelFormat(format);
+
+    aglEnable(gAGLContext, GL_BLEND);
+    aglEnable(gAGLContext, GL_LINE_SMOOTH);
+    aglEnable(gAGLContext, GL_POINT_SMOOTH);
+    aglEnable(gAGLContext, GL_POLYGON_SMOOTH);
+    
+    aglSetCurrentContext(gAGLContext);
+}
+
+static void setup_offscreen_gl(const SkBitmap& offscreen, WindowRef wref) {
+    GLboolean success = true;
+
+#ifdef USE_OFFSCREEN
+    success = aglSetOffScreen(gAGLContext,
+                                        offscreen.width(),
+                                        offscreen.height(),
+                                        offscreen.rowBytes(),
+                                        offscreen.getPixels());
+#else
+    success = aglSetWindowRef(gAGLContext, wref);
+#endif
+
+    GLenum err = aglGetError();
+    if (err) {
+        SkDebugf("---- setoffscreen %d %d %s [%d %d]\n", success, err,
+                 aglErrorString(err), offscreen.width(), offscreen.height());
+    }
+    
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
+    glEnable(GL_TEXTURE_2D);
+
+    glClearColor(0, 0, 0, 0);
+    glClear(GL_COLOR_BUFFER_BIT);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+static const char gTitleEvtName[] = "SampleCode_Title_Event";
+static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
+
+bool SampleCode::TitleQ(const SkEvent& evt) {
+    return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
+}
+
+void SampleCode::TitleR(SkEvent* evt, const char title[]) {
+    SkASSERT(evt && TitleQ(*evt));
+    evt->setString(gTitleEvtName, title);
+}
+
+bool SampleCode::PrefSizeQ(const SkEvent& evt) {
+    return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
+}
+
+void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
+    SkASSERT(evt && PrefSizeQ(*evt));
+    SkScalar size[2];
+    size[0] = width;
+    size[1] = height;
+    evt->setScalars(gPrefSizeEvtName, 2, size);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+class SampleWindow : public SkOSWindow {
+public:
+	SampleWindow(void* hwnd);
+	virtual ~SampleWindow();
+
+protected:
+    virtual void onDraw(SkCanvas* canvas);
+	virtual bool onHandleKey(SkKey key);
+    virtual bool onHandleChar(SkUnichar);
+    virtual void onSizeChange();
+    
+    virtual SkCanvas* beforeChildren(SkCanvas*);
+    virtual void afterChildren(SkCanvas*);
+
+	virtual bool onEvent(const SkEvent& evt);
+
+#if 0
+	virtual bool handleChar(SkUnichar uni);
+	virtual bool handleEvent(const SkEvent& evt);
+	virtual bool handleKey(SkKey key);
+	virtual bool handleKeyUp(SkKey key);
+    
+	virtual bool onClick(Click* click);
+	virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
+    virtual bool onHandleKeyUp(SkKey key);
+#endif
+private:
+    const SkViewRegister* fCurr;
+    
+    SkPicture* fPicture;
+    SkGLCanvas* fGLCanvas;
+    SkPath fClipPath;
+    
+    enum CanvasType {
+        kRaster_CanvasType,
+        kPicture_CanvasType,
+        kOpenGL_CanvasType
+    };
+    CanvasType fCanvasType;
+
+    bool fUseClip;
+    bool fRepeatDrawing;
+    bool fAnimating;
+    
+    int fScrollTestX, fScrollTestY;
+    
+    void loadView(SkView*);
+    void updateTitle();
+    bool nextSample();
+
+    void postAnimatingEvent() {
+        if (fAnimating) {
+            SkEvent* evt = new SkEvent(ANIMATING_EVENTTYPE);
+            evt->post(this->getSinkID(), ANIMATING_DELAY);
+        }
+    }
+    
+    
+    static CanvasType cycle_canvastype(CanvasType);
+
+    typedef SkOSWindow INHERITED;
+};
+
+SampleWindow::CanvasType SampleWindow::cycle_canvastype(CanvasType ct) {
+    static const CanvasType gCT[] = {
+        kPicture_CanvasType,
+        kOpenGL_CanvasType,
+        kRaster_CanvasType
+    };
+    return gCT[ct];
+}
+
+SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) {
+    init_gl((WindowRef)hwnd);
+    
+    fPicture = NULL;
+    fGLCanvas = NULL;
+
+    fCanvasType = kRaster_CanvasType;
+    fUseClip = false;
+    fRepeatDrawing = false;
+    fAnimating = false;
+
+    fScrollTestX = fScrollTestY = 0;
+
+//	this->setConfig(SkBitmap::kRGB_565_Config);
+	this->setConfig(SkBitmap::kARGB_8888_Config);
+	this->setVisibleP(true);
+
+    fCurr = SkViewRegister::Head();
+    this->loadView(fCurr->factory()());
+}
+
+SampleWindow::~SampleWindow() {
+    delete fPicture;
+    delete fGLCanvas;
+}
+
+void SampleWindow::onDraw(SkCanvas* canvas) {
+    if (fRepeatDrawing) {
+        this->inval(NULL);
+    }
+}
+
+#include "SkColorPriv.h"
+
+static void reverseRedAndBlue(const SkBitmap& bm) {
+    SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config);
+    uint8_t* p = (uint8_t*)bm.getPixels();
+    uint8_t* stop = p + bm.getSize();
+    while (p < stop) {
+        // swap red/blue (to go from ARGB(int) to RGBA(memory) and premultiply
+        unsigned scale = SkAlpha255To256(p[3]);
+        unsigned r = p[2];
+        unsigned b = p[0];
+        p[0] = SkAlphaMul(r, scale);
+        p[1] = SkAlphaMul(p[1], scale);
+        p[2] = SkAlphaMul(b, scale);
+        p += 4;
+    }
+}
+
+SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
+#ifndef USE_OFFSCREEN
+    aglSetWindowRef(gAGLContext, NULL);
+#endif
+    switch (fCanvasType) {
+        case kRaster_CanvasType:
+            canvas = this->INHERITED::beforeChildren(canvas);
+            break;
+        case kPicture_CanvasType:
+            fPicture = new SkPicture;
+            canvas = fPicture->beginRecording(9999, 9999);
+            break;
+        case kOpenGL_CanvasType: {
+            //SkGLCanvas::DeleteAllTextures();  // just for testing
+            SkDevice* device = canvas->getDevice();
+            const SkBitmap& bitmap = device->accessBitmap(true);
+            // first clear the raster bitmap, so we don't see any leftover bits
+            bitmap.eraseColor(0);
+            // now setup our glcanvas
+            setup_offscreen_gl(bitmap, (WindowRef)this->getHWND());
+            fGLCanvas = new SkGLCanvas;
+            fGLCanvas->setViewport(bitmap.width(), bitmap.height());
+            canvas = fGLCanvas;
+            break;
+        }
+    }
+
+    if (fUseClip) {
+        canvas->drawColor(0xFFFF88FF);
+        canvas->clipPath(fClipPath);
+    }
+
+    return canvas;
+}
+
+static void paint_rgn(const SkBitmap& bm, const SkIRect& r,
+                      const SkRegion& rgn) {
+    SkCanvas    canvas(bm);
+    SkRegion    inval(rgn);
+
+    inval.translate(r.fLeft, r.fTop);
+    canvas.clipRegion(inval);
+    canvas.drawColor(0xFFFF8080);
+}
+
+void SampleWindow::afterChildren(SkCanvas* orig) {
+    switch (fCanvasType) {
+        case kRaster_CanvasType:
+            break;
+        case kPicture_CanvasType:
+            if (false) {
+                SkPicture* pict = new SkPicture(*fPicture);
+                fPicture->unref();
+                orig->drawPicture(*pict);
+                pict->unref();
+            } if (true) {
+                SkDynamicMemoryWStream ostream;
+                fPicture->serialize(&ostream);
+                fPicture->unref();
+                
+                SkMemoryStream istream(ostream.getStream(), ostream.getOffset());
+                SkPicture pict(&istream);
+                orig->drawPicture(pict);
+            } else {
+                fPicture->draw(orig);
+                fPicture->unref();
+            }
+            fPicture = NULL;
+            break;
+        case kOpenGL_CanvasType:
+            glFlush();
+            delete fGLCanvas;
+            fGLCanvas = NULL;
+#ifdef USE_OFFSCREEN
+            reverseRedAndBlue(orig->getDevice()->accessBitmap(true));
+#endif
+            break;
+    }
+    
+//    if ((fScrollTestX | fScrollTestY) != 0)
+    {
+        const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
+        int dx = fScrollTestX * 7;
+        int dy = fScrollTestY * 7;
+        SkIRect r;
+        SkRegion inval;
+        
+        r.set(50, 50, 50+100, 50+100);
+        bm.scrollRect(&r, dx, dy, &inval);
+        paint_rgn(bm, r, inval);
+    }
+}
+
+static SkBitmap::Config gConfigCycle[] = {
+    SkBitmap::kNo_Config,           // none -> none
+    SkBitmap::kNo_Config,           // a1 -> none
+    SkBitmap::kNo_Config,           // a8 -> none
+    SkBitmap::kNo_Config,           // index8 -> none
+    SkBitmap::kARGB_4444_Config,    // 565 -> 4444
+    SkBitmap::kARGB_8888_Config,    // 4444 -> 8888
+    SkBitmap::kRGB_565_Config       // 8888 -> 565
+};
+
+static SkBitmap::Config cycle_configs(SkBitmap::Config c) {
+    return gConfigCycle[c];
+}
+
+bool SampleWindow::nextSample() {
+    if (fCurr) {
+        fCurr = fCurr->next();
+        if (NULL == fCurr) {
+            fCurr = SkViewRegister::Head();
+        }
+        this->loadView(fCurr->factory()());
+        return true;
+    }
+    return false;
+}
+
+bool SampleWindow::onEvent(const SkEvent& evt) {
+    if (evt.isType(ANIMATING_EVENTTYPE)) {
+        if (fAnimating) {
+            this->nextSample();
+            this->postAnimatingEvent();
+        }
+        return true;
+    }
+    return this->INHERITED::onEvent(evt);
+}
+
+
+bool SampleWindow::onHandleChar(SkUnichar uni) {
+    int dx = 0xFF;
+    int dy = 0xFF;
+
+    switch (uni) {
+        case '5': dx =  0; dy =  0; break;
+        case '8': dx =  0; dy = -1; break;
+        case '6': dx =  1; dy =  0; break;
+        case '2': dx =  0; dy =  1; break;
+        case '4': dx = -1; dy =  0; break;
+        case '7': dx = -1; dy = -1; break;
+        case '9': dx =  1; dy = -1; break;
+        case '3': dx =  1; dy =  1; break;
+        case '1': dx = -1; dy =  1; break;
+            
+        default:
+            break;
+    }
+    
+    if (0xFF != dx && 0xFF != dy) {
+        if ((dx | dy) == 0) {
+            fScrollTestX = fScrollTestY = 0;
+        } else {
+            fScrollTestX += dx;
+            fScrollTestY += dy;
+        }
+        this->inval(NULL);
+        return true;
+    }
+    
+    if ('a' == uni) {
+        fAnimating = !fAnimating;
+        this->postAnimatingEvent();
+        this->updateTitle();
+    }
+    
+    return this->INHERITED::onHandleChar(uni);
+}
+
+#include "SkDumpCanvas.h"
+
+bool SampleWindow::onHandleKey(SkKey key) {
+    switch (key) {
+        case kRight_SkKey:
+            if (this->nextSample()) {
+                return true;
+            }
+            break;
+        case kLeft_SkKey:
+            fCanvasType = cycle_canvastype(fCanvasType);
+            this->updateTitle();
+            this->inval(NULL);
+            return true;
+        case kUp_SkKey:
+            fUseClip = !fUseClip;
+            this->updateTitle();
+            this->inval(NULL);
+            return true;
+        case kDown_SkKey:
+            this->setConfig(cycle_configs(this->getBitmap().config()));
+            this->updateTitle();
+            return true;
+        case kOK_SkKey:
+            if (true) {
+                SkDebugfDumper dumper;
+                SkDumpCanvas dc(&dumper);
+                this->draw(&dc);
+            } else {
+                fRepeatDrawing = !fRepeatDrawing;
+                if (fRepeatDrawing) {
+                    this->inval(NULL);
+                }
+            }
+            return true;
+        default:
+            break;
+    }
+    return this->INHERITED::onHandleKey(key);
+}
+
+void SampleWindow::loadView(SkView* view) {
+    SkView::F2BIter iter(this);
+    SkView* prev = iter.next();
+    if (prev) {
+        prev->detachFromParent();
+    }
+    view->setVisibleP(true);
+    this->attachChildToFront(view)->unref();
+    view->setSize(this->width(), this->height());
+
+    this->updateTitle();
+}
+
+static const char* gConfigNames[] = {
+    "unknown config",
+    "A1",
+    "A8",
+    "Index8",
+    "565",
+    "4444",
+    "8888"
+};
+
+static const char* configToString(SkBitmap::Config c) {
+    return gConfigNames[c];
+}
+
+static const char* gCanvasTypePrefix[] = {
+    "raster: ",
+    "picture: ",
+    "opengl: "
+};
+
+void SampleWindow::updateTitle() {
+    SkString title;
+
+    SkView::F2BIter iter(this);
+    SkView* view = iter.next();
+    SkEvent evt(gTitleEvtName);
+    if (view->doQuery(&evt)) {
+        title.set(evt.findString(gTitleEvtName));
+    }
+    if (title.size() == 0) {
+        title.set("<unknown>");
+    }
+    
+    title.prepend(gCanvasTypePrefix[fCanvasType]);
+
+    title.prepend(" ");
+    title.prepend(configToString(this->getBitmap().config()));
+    
+    if (fAnimating) {
+        title.prepend("<A> ");
+    }
+
+    this->setTitle(title.c_str());
+}
+
+void SampleWindow::onSizeChange() {
+    this->INHERITED::onSizeChange();
+
+    SkView::F2BIter iter(this);
+    SkView* view = iter.next();
+    view->setSize(this->width(), this->height());
+    
+    // rebuild our clippath
+    {
+        const SkScalar W = this->width();
+        const SkScalar H = this->height();
+        
+        fClipPath.reset();
+#if 0
+        for (SkScalar y = SK_Scalar1; y < H; y += SkIntToScalar(32)) {
+            SkRect r;
+            r.set(SK_Scalar1, y, SkIntToScalar(30), y + SkIntToScalar(30));
+            for (; r.fLeft < W; r.offset(SkIntToScalar(32), 0))
+                fClipPath.addRect(r);
+        }
+#else
+        SkRect r;
+        r.set(0, 0, W, H);
+        fClipPath.addRect(r, SkPath::kCCW_Direction);
+        r.set(W/4, H/4, W*3/4, H*3/4);
+        fClipPath.addRect(r, SkPath::kCW_Direction);
+#endif
+    }
+    
+    this->updateTitle();    // to refresh our config
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkOSWindow* create_sk_window(void* hwnd) {
+	return new SampleWindow(hwnd);
+}
+
+void get_preferred_size(int* x, int* y, int* width, int* height) {
+    *x = 10;
+    *y = 50;
+    *width = 640;
+    *height = 480;
+}
+
+void application_init() {
+//    setenv("ANDROID_ROOT", "../../../data", 0);
+    setenv("ANDROID_ROOT", "/android/device/data", 0);
+	SkGraphics::Init(true);
+	SkEvent::Init();
+}
+
+void application_term() {
+	SkEvent::Term();
+	SkGraphics::Term();
+}
