grab from latest android



git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/views/SkWindow.cpp b/src/views/SkWindow.cpp
new file mode 100644
index 0000000..5d00d4f
--- /dev/null
+++ b/src/views/SkWindow.cpp
@@ -0,0 +1,367 @@
+#include "SkWindow.h"
+#include "SkCanvas.h"
+#include "SkOSMenu.h"
+#include "SkSystemEventTypes.h"
+#include "SkTime.h"
+
+#define SK_EventDelayInval "\xd" "n" "\xa" "l"
+
+#define TEST_BOUNDERx
+
+#include "SkBounder.h"
+class test_bounder : public SkBounder {
+public:
+	test_bounder(const SkBitmap& bm) : fCanvas(bm) {}
+protected:
+	virtual bool onIRect(const SkIRect& r)
+	{
+		SkRect	rr;
+
+		rr.set(SkIntToScalar(r.fLeft), SkIntToScalar(r.fTop),
+				SkIntToScalar(r.fRight), SkIntToScalar(r.fBottom));
+
+		SkPaint	p;
+
+		p.setStyle(SkPaint::kStroke_Style);
+		p.setColor(SK_ColorYELLOW);
+
+#if 0
+		rr.inset(SK_ScalarHalf, SK_ScalarHalf);
+#else
+		rr.inset(-SK_ScalarHalf, -SK_ScalarHalf);
+#endif
+
+		fCanvas.drawRect(rr, p);
+		return true;
+	}
+private:
+	SkCanvas	fCanvas;
+};
+
+SkWindow::SkWindow() : fFocusView(NULL)
+{
+	fClick = NULL;
+	fWaitingOnInval = false;
+
+#ifdef SK_BUILD_FOR_WINCE
+	fConfig = SkBitmap::kRGB_565_Config;
+#else
+	fConfig = SkBitmap::kARGB_8888_Config;
+#endif
+}
+
+SkWindow::~SkWindow()
+{
+	delete fClick;
+
+	fMenus.deleteAll();
+}
+
+void SkWindow::setConfig(SkBitmap::Config config)
+{
+	this->resize(fBitmap.width(), fBitmap.height(), config);
+}
+
+#include "SkImageDecoder.h"
+
+void SkWindow::resize(int width, int height, SkBitmap::Config config)
+{
+	if (config == SkBitmap::kNo_Config)
+		config = fConfig;
+
+	if (width != fBitmap.width() || height != fBitmap.height() || config != fConfig)
+	{
+		fConfig = config;
+		fBitmap.setConfig(config, width, height);
+		fBitmap.allocPixels();
+
+		this->setSize(SkIntToScalar(width), SkIntToScalar(height));
+		this->inval(NULL);
+	}
+
+	SkImageDecoder::SetDeviceConfig(fConfig);
+}
+
+void SkWindow::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
+{
+	fBitmap.eraseARGB(a, r, g, b);
+}
+
+void SkWindow::eraseRGB(U8CPU r, U8CPU g, U8CPU b)
+{
+	fBitmap.eraseRGB(r, g, b);
+}
+
+bool SkWindow::handleInval(const SkRect& r)
+{
+	SkIRect	ir;
+
+	r.round(&ir);
+	fDirtyRgn.op(ir, SkRegion::kUnion_Op);
+
+#ifdef SK_BUILD_FOR_WIN32
+	if (!fWaitingOnInval)
+	{
+		fWaitingOnInval = true;
+		(new SkEvent(SK_EventDelayInval))->post(this->getSinkID(), 10);
+	}
+#else
+	this->onHandleInval(ir);
+#endif
+	return true;
+}
+
+#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
+	#include <windows.h>
+	#include <gx.h>
+	extern GXDisplayProperties gDisplayProps;
+#endif
+
+#ifdef SK_SIMULATE_FAILED_MALLOC
+extern bool gEnableControlledThrow;
+#endif
+
+bool SkWindow::update(SkIRect* updateArea)
+{
+	if (!fDirtyRgn.isEmpty())
+	{
+		SkBitmap bm = this->getBitmap();
+
+#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
+		char* buffer = (char*)GXBeginDraw();
+		SkASSERT(buffer);
+
+		RECT	rect;
+		GetWindowRect((HWND)((SkOSWindow*)this)->getHWND(), &rect);
+		buffer += rect.top * gDisplayProps.cbyPitch + rect.left * gDisplayProps.cbxPitch;
+
+		bm.setPixels(buffer);
+#endif
+
+		SkCanvas	canvas(bm);
+
+		canvas.clipRegion(fDirtyRgn);
+		if (updateArea)
+			*updateArea = fDirtyRgn.getBounds();
+
+		// empty this now, so we can correctly record any inval calls that
+		// might be made during the draw call.
+		fDirtyRgn.setEmpty();
+
+#ifdef TEST_BOUNDER
+		test_bounder	b(bm);
+		canvas.setBounder(&b);
+#endif
+#ifdef SK_SIMULATE_FAILED_MALLOC
+		gEnableControlledThrow = true;
+#endif
+#ifdef SK_BUILD_FOR_WIN32
+		try {
+			this->draw(&canvas);
+		}
+		catch (...) {
+		}
+#else
+		this->draw(&canvas);
+#endif
+#ifdef SK_SIMULATE_FAILED_MALLOC
+		gEnableControlledThrow = false;
+#endif
+#ifdef TEST_BOUNDER
+		canvas.setBounder(NULL);
+#endif
+
+#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
+		GXEndDraw();
+#endif
+
+		return true;
+	}
+	return false;
+}
+
+bool SkWindow::handleChar(SkUnichar uni)
+{
+	if (this->onHandleChar(uni))
+		return true;
+
+	SkView* focus = this->getFocusView();
+	if (focus == NULL)
+		focus = this;
+
+	SkEvent evt(SK_EventType_Unichar);
+	evt.setFast32(uni);
+	return focus->doEvent(evt);
+}
+
+bool SkWindow::handleKey(SkKey key)
+{
+	if (key == kNONE_SkKey)
+		return false;
+
+	if (this->onHandleKey(key))
+		return true;
+
+	// send an event to the focus-view
+	{
+		SkView* focus = this->getFocusView();
+		if (focus == NULL)
+			focus = this;
+
+		SkEvent evt(SK_EventType_Key);
+		evt.setFast32(key);
+		if (focus->doEvent(evt))
+			return true;
+	}
+
+	if (key == kUp_SkKey || key == kDown_SkKey)
+	{
+		if (this->moveFocus(key == kUp_SkKey ? kPrev_FocusDirection : kNext_FocusDirection) == NULL)
+			this->onSetFocusView(NULL);
+		return true;
+	}
+	return false;
+}
+
+bool SkWindow::handleKeyUp(SkKey key)
+{
+    if (key == kNONE_SkKey)
+        return false;
+        
+    if (this->onHandleKeyUp(key))
+        return true;
+    
+    //send an event to the focus-view
+    {
+        SkView* focus = this->getFocusView();
+        if (focus == NULL)
+            focus = this;
+            
+        //should this one be the same?
+        SkEvent evt(SK_EventType_KeyUp);
+        evt.setFast32(key);
+        if (focus->doEvent(evt))
+            return true;
+    }
+    return false;
+}
+
+void SkWindow::addMenu(SkOSMenu* menu)
+{
+	*fMenus.append() = menu;
+	this->onAddMenu(menu);
+}
+
+void SkWindow::setTitle(const char title[])
+{
+    if (NULL == title)
+        title = "";
+    this->onSetTitle(title);
+}
+
+bool SkWindow::handleMenu(uint32_t cmd)
+{
+	for (int i = 0; i < fMenus.count(); i++)
+	{
+		SkEvent* evt = fMenus[i]->createEvent(cmd);
+		if (evt)
+		{
+			evt->post(this->getSinkID());
+			return true;
+		}
+	}
+	return false;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+bool SkWindow::onEvent(const SkEvent& evt)
+{
+	if (evt.isType(SK_EventDelayInval))
+	{
+		SkRegion::Iterator	iter(fDirtyRgn);
+
+		for (; !iter.done(); iter.next())
+			this->onHandleInval(iter.rect());
+		fWaitingOnInval = false;
+		return true;
+	}
+	return this->INHERITED::onEvent(evt);
+}
+
+bool SkWindow::onGetFocusView(SkView** focus) const
+{
+	if (focus)
+		*focus = fFocusView;
+	return true;
+}
+
+bool SkWindow::onSetFocusView(SkView* focus)
+{
+	if (fFocusView != focus)
+	{
+		if (fFocusView)
+			fFocusView->onFocusChange(false);
+		fFocusView = focus;
+		if (focus)
+			focus->onFocusChange(true);
+	}
+	return true;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+void SkWindow::onHandleInval(const SkIRect&)
+{
+}
+
+bool SkWindow::onHandleChar(SkUnichar)
+{
+	return false;
+}
+
+bool SkWindow::onHandleKey(SkKey key)
+{
+	return false;
+}
+
+bool SkWindow::onHandleKeyUp(SkKey key)
+{
+    return false;
+}
+
+bool SkWindow::handleClick(int x, int y, Click::State state)
+{
+	bool handled = false;
+
+	switch (state) {
+	case Click::kDown_State:
+		if (fClick)
+			delete fClick;
+		fClick = this->findClickHandler(SkIntToScalar(x), SkIntToScalar(y));
+		if (fClick)
+		{
+			SkView::DoClickDown(fClick, x, y);
+			handled = true;
+		}
+		break;
+	case Click::kMoved_State:
+		if (fClick)
+		{
+			SkView::DoClickMoved(fClick, x, y);
+			handled = true;
+		}
+		break;
+	case Click::kUp_State:
+		if (fClick)
+		{
+			SkView::DoClickUp(fClick, x, y);
+			delete fClick;
+			fClick = NULL;
+			handled = true;
+		}
+		break;
+	}
+	return handled;
+}
+