2 * Copyright 2011 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
11 #include "SkSurface.h"
12 #include "SkSystemEventTypes.h"
15 #define SK_EventDelayInval "\xd" "n" "\xa" "l"
17 SkWindow::SkWindow() : fFocusView(NULL) {
19 fWaitingOnInval = false;
21 #ifdef SK_BUILD_FOR_WINCE
22 fColorType = kRGB_565_SkColorType;
24 fColorType = kN32_SkColorType;
30 SkWindow::~SkWindow() {
35 SkSurface* SkWindow::createSurface() {
36 const SkBitmap& bm = this->getBitmap();
37 return SkSurface::NewRasterDirect(bm.info(), bm.getPixels(), bm.rowBytes());
40 void SkWindow::setMatrix(const SkMatrix& matrix) {
41 if (fMatrix != matrix) {
47 void SkWindow::preConcat(const SkMatrix& matrix) {
49 m.setConcat(fMatrix, matrix);
53 void SkWindow::postConcat(const SkMatrix& matrix) {
55 m.setConcat(matrix, fMatrix);
59 void SkWindow::setColorType(SkColorType ct) {
60 this->resize(fBitmap.width(), fBitmap.height(), ct);
63 void SkWindow::resize(int width, int height, SkColorType ct) {
64 if (ct == kUnknown_SkColorType)
67 if (width != fBitmap.width() || height != fBitmap.height() || ct != fColorType) {
69 fBitmap.allocPixels(SkImageInfo::Make(width, height,
70 ct, kPremul_SkAlphaType));
72 this->setSize(SkIntToScalar(width), SkIntToScalar(height));
77 bool SkWindow::handleInval(const SkRect* localR) {
83 if (!fMatrix.invert(&inverse)) {
86 fMatrix.mapRect(&devR, *localR);
90 SkScalarRoundToInt(this->width()),
91 SkScalarRoundToInt(this->height()));
93 fDirtyRgn.op(ir, SkRegion::kUnion_Op);
95 this->onHandleInval(ir);
99 void SkWindow::forceInvalAll() {
100 fDirtyRgn.setRect(0, 0,
101 SkScalarCeilToInt(this->width()),
102 SkScalarCeilToInt(this->height()));
105 #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
108 extern GXDisplayProperties gDisplayProps;
111 #ifdef SK_SIMULATE_FAILED_MALLOC
112 extern bool gEnableControlledThrow;
115 bool SkWindow::update(SkIRect* updateArea) {
116 if (!fDirtyRgn.isEmpty()) {
117 SkBitmap bm = this->getBitmap();
119 #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
120 char* buffer = (char*)GXBeginDraw();
124 GetWindowRect((HWND)((SkOSWindow*)this)->getHWND(), &rect);
125 buffer += rect.top * gDisplayProps.cbyPitch + rect.left * gDisplayProps.cbxPitch;
127 bm.setPixels(buffer);
130 SkAutoTUnref<SkSurface> surface(this->createSurface());
131 SkCanvas* canvas = surface->getCanvas();
133 canvas->clipRegion(fDirtyRgn);
135 *updateArea = fDirtyRgn.getBounds();
137 SkAutoCanvasRestore acr(canvas, true);
138 canvas->concat(fMatrix);
140 // empty this now, so we can correctly record any inval calls that
141 // might be made during the draw call.
142 fDirtyRgn.setEmpty();
144 #ifdef SK_SIMULATE_FAILED_MALLOC
145 gEnableControlledThrow = true;
147 #ifdef SK_BUILD_FOR_WIN32
156 #ifdef SK_SIMULATE_FAILED_MALLOC
157 gEnableControlledThrow = false;
160 #if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
169 bool SkWindow::handleChar(SkUnichar uni) {
170 if (this->onHandleChar(uni))
173 SkView* focus = this->getFocusView();
177 SkEvent evt(SK_EventType_Unichar);
179 return focus->doEvent(evt);
182 bool SkWindow::handleKey(SkKey key) {
183 if (key == kNONE_SkKey)
186 if (this->onHandleKey(key))
189 // send an event to the focus-view
191 SkView* focus = this->getFocusView();
195 SkEvent evt(SK_EventType_Key);
197 if (focus->doEvent(evt))
201 if (key == kUp_SkKey || key == kDown_SkKey) {
202 if (this->moveFocus(key == kUp_SkKey ? kPrev_FocusDirection : kNext_FocusDirection) == NULL)
203 this->onSetFocusView(NULL);
209 bool SkWindow::handleKeyUp(SkKey key) {
210 if (key == kNONE_SkKey)
213 if (this->onHandleKeyUp(key))
216 //send an event to the focus-view
218 SkView* focus = this->getFocusView();
222 //should this one be the same?
223 SkEvent evt(SK_EventType_KeyUp);
225 if (focus->doEvent(evt))
231 void SkWindow::addMenu(SkOSMenu* menu) {
232 *fMenus.append() = menu;
233 this->onAddMenu(menu);
236 void SkWindow::setTitle(const char title[]) {
241 this->onSetTitle(title);
244 bool SkWindow::onEvent(const SkEvent& evt) {
245 if (evt.isType(SK_EventDelayInval)) {
246 for (SkRegion::Iterator iter(fDirtyRgn); !iter.done(); iter.next())
247 this->onHandleInval(iter.rect());
248 fWaitingOnInval = false;
251 return this->INHERITED::onEvent(evt);
254 bool SkWindow::onGetFocusView(SkView** focus) const {
260 bool SkWindow::onSetFocusView(SkView* focus) {
261 if (fFocusView != focus) {
263 fFocusView->onFocusChange(false);
266 focus->onFocusChange(true);
271 void SkWindow::onHandleInval(const SkIRect&) {
274 bool SkWindow::onHandleChar(SkUnichar) {
278 bool SkWindow::onHandleKey(SkKey) {
282 bool SkWindow::onHandleKeyUp(SkKey) {
286 bool SkWindow::handleClick(int x, int y, Click::State state, void *owner,
287 unsigned modifierKeys) {
288 return this->onDispatchClick(x, y, state, owner, modifierKeys);
291 bool SkWindow::onDispatchClick(int x, int y, Click::State state,
292 void* owner, unsigned modifierKeys) {
293 bool handled = false;
295 // First, attempt to find an existing click with this owner.
297 for (int i = 0; i < fClicks.count(); i++) {
298 if (owner == fClicks[i]->fOwner) {
305 case Click::kDown_State: {
307 delete fClicks[index];
308 fClicks.remove(index);
310 Click* click = this->findClickHandler(SkIntToScalar(x),
311 SkIntToScalar(y), modifierKeys);
314 click->fOwner = owner;
315 *fClicks.append() = click;
316 SkView::DoClickDown(click, x, y, modifierKeys);
321 case Click::kMoved_State:
323 SkView::DoClickMoved(fClicks[index], x, y, modifierKeys);
327 case Click::kUp_State:
329 SkView::DoClickUp(fClicks[index], x, y, modifierKeys);
330 delete fClicks[index];
331 fClicks.remove(index);