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