• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SkWindow.h"
2 #include "SkCanvas.h"
3 #include "SkDevice.h"
4 #include "SkOSMenu.h"
5 #include "SkSystemEventTypes.h"
6 #include "SkTime.h"
7 
8 #define SK_EventDelayInval "\xd" "n" "\xa" "l"
9 
10 #define TEST_BOUNDERx
11 
12 #include "SkBounder.h"
13 class test_bounder : public SkBounder {
14 public:
test_bounder(const SkBitmap & bm)15 	test_bounder(const SkBitmap& bm) : fCanvas(bm) {}
16 protected:
onIRect(const SkIRect & r)17 	virtual bool onIRect(const SkIRect& r)
18 	{
19 		SkRect	rr;
20 
21 		rr.set(SkIntToScalar(r.fLeft), SkIntToScalar(r.fTop),
22 				SkIntToScalar(r.fRight), SkIntToScalar(r.fBottom));
23 
24 		SkPaint	p;
25 
26 		p.setStyle(SkPaint::kStroke_Style);
27 		p.setColor(SK_ColorYELLOW);
28 
29 #if 0
30 		rr.inset(SK_ScalarHalf, SK_ScalarHalf);
31 #else
32 		rr.inset(-SK_ScalarHalf, -SK_ScalarHalf);
33 #endif
34 
35 		fCanvas.drawRect(rr, p);
36 		return true;
37 	}
38 private:
39 	SkCanvas	fCanvas;
40 };
41 
SkWindow()42 SkWindow::SkWindow() : fFocusView(NULL)
43 {
44 	fClick = NULL;
45 	fWaitingOnInval = false;
46 
47 #ifdef SK_BUILD_FOR_WINCE
48 	fConfig = SkBitmap::kRGB_565_Config;
49 #else
50 	fConfig = SkBitmap::kARGB_8888_Config;
51 #endif
52 
53     fMatrix.reset();
54 }
55 
~SkWindow()56 SkWindow::~SkWindow()
57 {
58 	delete fClick;
59 
60 	fMenus.deleteAll();
61 }
62 
setMatrix(const SkMatrix & matrix)63 void SkWindow::setMatrix(const SkMatrix& matrix) {
64     if (fMatrix != matrix) {
65         fMatrix = matrix;
66         this->inval(NULL);
67     }
68 }
69 
preConcat(const SkMatrix & matrix)70 void SkWindow::preConcat(const SkMatrix& matrix) {
71     SkMatrix m;
72     m.setConcat(fMatrix, matrix);
73     this->setMatrix(m);
74 }
75 
postConcat(const SkMatrix & matrix)76 void SkWindow::postConcat(const SkMatrix& matrix) {
77     SkMatrix m;
78     m.setConcat(matrix, fMatrix);
79     this->setMatrix(m);
80 }
81 
setConfig(SkBitmap::Config config)82 void SkWindow::setConfig(SkBitmap::Config config)
83 {
84 	this->resize(fBitmap.width(), fBitmap.height(), config);
85 }
86 
resize(int width,int height,SkBitmap::Config config)87 void SkWindow::resize(int width, int height, SkBitmap::Config config)
88 {
89 	if (config == SkBitmap::kNo_Config)
90 		config = fConfig;
91 
92 	if (width != fBitmap.width() || height != fBitmap.height() || config != fConfig)
93 	{
94 		fConfig = config;
95 		fBitmap.setConfig(config, width, height);
96 		fBitmap.allocPixels();
97         fBitmap.setIsOpaque(true);
98 
99 		this->setSize(SkIntToScalar(width), SkIntToScalar(height));
100 		this->inval(NULL);
101 	}
102 }
103 
eraseARGB(U8CPU a,U8CPU r,U8CPU g,U8CPU b)104 void SkWindow::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
105 {
106 	fBitmap.eraseARGB(a, r, g, b);
107 }
108 
eraseRGB(U8CPU r,U8CPU g,U8CPU b)109 void SkWindow::eraseRGB(U8CPU r, U8CPU g, U8CPU b)
110 {
111 	fBitmap.eraseRGB(r, g, b);
112 }
113 
handleInval(const SkRect * localR)114 bool SkWindow::handleInval(const SkRect* localR)
115 {
116 	SkIRect	ir;
117 
118     if (localR) {
119         SkRect devR;
120         SkMatrix inverse;
121         if (!fMatrix.invert(&inverse)) {
122             return false;
123         }
124         fMatrix.mapRect(&devR, *localR);
125         devR.round(&ir);
126     } else {
127         ir.set(0, 0,
128 			   SkScalarRound(this->width()),
129 			   SkScalarRound(this->height()));
130     }
131 	fDirtyRgn.op(ir, SkRegion::kUnion_Op);
132 
133 	this->onHandleInval(ir);
134 	return true;
135 }
136 
forceInvalAll()137 void SkWindow::forceInvalAll() {
138     fDirtyRgn.setRect(0, 0,
139                       SkScalarCeil(this->width()),
140                       SkScalarCeil(this->height()));
141 }
142 
143 #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
144 	#include <windows.h>
145 	#include <gx.h>
146 	extern GXDisplayProperties gDisplayProps;
147 #endif
148 
149 #ifdef SK_SIMULATE_FAILED_MALLOC
150 extern bool gEnableControlledThrow;
151 #endif
152 
update(SkIRect * updateArea,SkCanvas * canvas)153 bool SkWindow::update(SkIRect* updateArea, SkCanvas* canvas)
154 {
155 	if (!fDirtyRgn.isEmpty())
156 	{
157 		SkBitmap bm = this->getBitmap();
158 
159 #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
160 		char* buffer = (char*)GXBeginDraw();
161 		SkASSERT(buffer);
162 
163 		RECT	rect;
164 		GetWindowRect((HWND)((SkOSWindow*)this)->getHWND(), &rect);
165 		buffer += rect.top * gDisplayProps.cbyPitch + rect.left * gDisplayProps.cbxPitch;
166 
167 		bm.setPixels(buffer);
168 #endif
169 
170 		SkCanvas	rasterCanvas;
171         SkDevice*   device;
172 
173         if (NULL == canvas) {
174             canvas = &rasterCanvas;
175             device = new SkDevice(canvas, bm, false);
176             canvas->setDevice(device)->unref();
177         } else {
178             canvas->setBitmapDevice(bm);
179         }
180 
181 		canvas->clipRegion(fDirtyRgn);
182 		if (updateArea)
183 			*updateArea = fDirtyRgn.getBounds();
184 
185         SkAutoCanvasRestore acr(canvas, true);
186         canvas->concat(fMatrix);
187 
188 		// empty this now, so we can correctly record any inval calls that
189 		// might be made during the draw call.
190 		fDirtyRgn.setEmpty();
191 
192 #ifdef TEST_BOUNDER
193 		test_bounder	b(bm);
194 		canvas->setBounder(&b);
195 #endif
196 #ifdef SK_SIMULATE_FAILED_MALLOC
197 		gEnableControlledThrow = true;
198 #endif
199 #ifdef SK_BUILD_FOR_WIN32
200 		//try {
201 			this->draw(canvas);
202 		//}
203 		//catch (...) {
204 		//}
205 #else
206 		this->draw(canvas);
207 #endif
208 #ifdef SK_SIMULATE_FAILED_MALLOC
209 		gEnableControlledThrow = false;
210 #endif
211 #ifdef TEST_BOUNDER
212 		canvas->setBounder(NULL);
213 #endif
214 
215 #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
216 		GXEndDraw();
217 #endif
218 
219 		return true;
220 	}
221 	return false;
222 }
223 
handleChar(SkUnichar uni)224 bool SkWindow::handleChar(SkUnichar uni)
225 {
226 	if (this->onHandleChar(uni))
227 		return true;
228 
229 	SkView* focus = this->getFocusView();
230 	if (focus == NULL)
231 		focus = this;
232 
233 	SkEvent evt(SK_EventType_Unichar);
234 	evt.setFast32(uni);
235 	return focus->doEvent(evt);
236 }
237 
handleKey(SkKey key)238 bool SkWindow::handleKey(SkKey key)
239 {
240 	if (key == kNONE_SkKey)
241 		return false;
242 
243 	if (this->onHandleKey(key))
244 		return true;
245 
246 	// send an event to the focus-view
247 	{
248 		SkView* focus = this->getFocusView();
249 		if (focus == NULL)
250 			focus = this;
251 
252 		SkEvent evt(SK_EventType_Key);
253 		evt.setFast32(key);
254 		if (focus->doEvent(evt))
255 			return true;
256 	}
257 
258 	if (key == kUp_SkKey || key == kDown_SkKey)
259 	{
260 		if (this->moveFocus(key == kUp_SkKey ? kPrev_FocusDirection : kNext_FocusDirection) == NULL)
261 			this->onSetFocusView(NULL);
262 		return true;
263 	}
264 	return false;
265 }
266 
handleKeyUp(SkKey key)267 bool SkWindow::handleKeyUp(SkKey key)
268 {
269     if (key == kNONE_SkKey)
270         return false;
271 
272     if (this->onHandleKeyUp(key))
273         return true;
274 
275     //send an event to the focus-view
276     {
277         SkView* focus = this->getFocusView();
278         if (focus == NULL)
279             focus = this;
280 
281         //should this one be the same?
282         SkEvent evt(SK_EventType_KeyUp);
283         evt.setFast32(key);
284         if (focus->doEvent(evt))
285             return true;
286     }
287     return false;
288 }
289 
addMenu(SkOSMenu * menu)290 void SkWindow::addMenu(SkOSMenu* menu)
291 {
292 	*fMenus.append() = menu;
293 	this->onAddMenu(menu);
294 }
295 
setTitle(const char title[])296 void SkWindow::setTitle(const char title[]) {
297     if (NULL == title) {
298         title = "";
299     }
300     fTitle.set(title);
301     this->onSetTitle(title);
302 }
303 
handleMenu(uint32_t cmd)304 bool SkWindow::handleMenu(uint32_t cmd)
305 {
306 	for (int i = 0; i < fMenus.count(); i++)
307 	{
308 		SkEvent* evt = fMenus[i]->createEvent(cmd);
309 		if (evt)
310 		{
311 			evt->post(this->getSinkID());
312 			return true;
313 		}
314 	}
315 	return false;
316 }
317 
318 //////////////////////////////////////////////////////////////////////
319 
onEvent(const SkEvent & evt)320 bool SkWindow::onEvent(const SkEvent& evt)
321 {
322 	if (evt.isType(SK_EventDelayInval))
323 	{
324 		SkRegion::Iterator	iter(fDirtyRgn);
325 
326 		for (; !iter.done(); iter.next())
327 			this->onHandleInval(iter.rect());
328 		fWaitingOnInval = false;
329 		return true;
330 	}
331 	return this->INHERITED::onEvent(evt);
332 }
333 
onGetFocusView(SkView ** focus) const334 bool SkWindow::onGetFocusView(SkView** focus) const
335 {
336 	if (focus)
337 		*focus = fFocusView;
338 	return true;
339 }
340 
onSetFocusView(SkView * focus)341 bool SkWindow::onSetFocusView(SkView* focus)
342 {
343 	if (fFocusView != focus)
344 	{
345 		if (fFocusView)
346 			fFocusView->onFocusChange(false);
347 		fFocusView = focus;
348 		if (focus)
349 			focus->onFocusChange(true);
350 	}
351 	return true;
352 }
353 
354 //////////////////////////////////////////////////////////////////////
355 
onHandleInval(const SkIRect &)356 void SkWindow::onHandleInval(const SkIRect&)
357 {
358 }
359 
onHandleChar(SkUnichar)360 bool SkWindow::onHandleChar(SkUnichar)
361 {
362 	return false;
363 }
364 
onHandleKey(SkKey key)365 bool SkWindow::onHandleKey(SkKey key)
366 {
367 	return false;
368 }
369 
onHandleKeyUp(SkKey key)370 bool SkWindow::onHandleKeyUp(SkKey key)
371 {
372     return false;
373 }
374 
handleClick(int x,int y,Click::State state)375 bool SkWindow::handleClick(int x, int y, Click::State state) {
376     return this->onDispatchClick(x, y, state);
377 }
378 
onDispatchClick(int x,int y,Click::State state)379 bool SkWindow::onDispatchClick(int x, int y, Click::State state) {
380 	bool handled = false;
381 
382 	switch (state) {
383 	case Click::kDown_State:
384 		if (fClick)
385 			delete fClick;
386 		fClick = this->findClickHandler(SkIntToScalar(x), SkIntToScalar(y));
387 		if (fClick)
388 		{
389 			SkView::DoClickDown(fClick, x, y);
390 			handled = true;
391 		}
392 		break;
393 	case Click::kMoved_State:
394 		if (fClick)
395 		{
396 			SkView::DoClickMoved(fClick, x, y);
397 			handled = true;
398 		}
399 		break;
400 	case Click::kUp_State:
401 		if (fClick)
402 		{
403 			SkView::DoClickUp(fClick, x, y);
404 			delete fClick;
405 			fClick = NULL;
406 			handled = true;
407 		}
408 		break;
409 	}
410 	return handled;
411 }
412 
413