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: 14 test_bounder(const SkBitmap& bm) : fCanvas(bm) {} 15 protected: 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 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 53 SkWindow::~SkWindow() 54 { 55 delete fClick; 56 57 fMenus.deleteAll(); 58 } 59 60 void SkWindow::setConfig(SkBitmap::Config config) 61 { 62 this->resize(fBitmap.width(), fBitmap.height(), config); 63 } 64 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 81 void SkWindow::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) 82 { 83 fBitmap.eraseARGB(a, r, g, b); 84 } 85 86 void SkWindow::eraseRGB(U8CPU r, U8CPU g, U8CPU b) 87 { 88 fBitmap.eraseRGB(r, g, b); 89 } 90 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 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 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 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 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 245 void SkWindow::addMenu(SkOSMenu* menu) 246 { 247 *fMenus.append() = menu; 248 this->onAddMenu(menu); 249 } 250 251 void SkWindow::setTitle(const char title[]) { 252 if (NULL == title) { 253 title = ""; 254 } 255 fTitle.set(title); 256 this->onSetTitle(title); 257 } 258 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 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 289 bool SkWindow::onGetFocusView(SkView** focus) const 290 { 291 if (focus) 292 *focus = fFocusView; 293 return true; 294 } 295 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 311 void SkWindow::onHandleInval(const SkIRect&) 312 { 313 } 314 315 bool SkWindow::onHandleChar(SkUnichar) 316 { 317 return false; 318 } 319 320 bool SkWindow::onHandleKey(SkKey key) 321 { 322 return false; 323 } 324 325 bool SkWindow::onHandleKeyUp(SkKey key) 326 { 327 return false; 328 } 329 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