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