diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/views/sdl/SkOSWindow_SDL.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/views/sdl/SkOSWindow_SDL.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,226 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "SkOSWindow_SDL.h" +#include "SkCanvas.h" +#include "SkColorPriv.h" +#include "SkGLCanvas.h" +#include "SkOSMenu.h" +#include "SkTime.h" + +static void post_SkEvent_event() { + SDL_Event evt; + evt.type = SDL_USEREVENT; + evt.user.type = SDL_USEREVENT; + evt.user.code = 0; + evt.user.data1 = NULL; + evt.user.data2 = NULL; + SDL_PushEvent(&evt); +} + +static bool skia_setBitmapFromSurface(SkBitmap* dst, SDL_Surface* src) { + SkBitmap::Config config; + + switch (src->format->BytesPerPixel) { + case 2: + config = SkBitmap::kRGB_565_Config; + break; + case 4: + config = SkBitmap::kARGB_8888_Config; + break; + default: + return false; + } + + dst->setConfig(config, src->w, src->h, src->pitch); + dst->setPixels(src->pixels); + return true; +} + +SkOSWindow::SkOSWindow(void* screen) { + fScreen = reinterpret_cast(screen); + this->resize(fScreen->w, fScreen->h); + + uint32_t rmask = SK_R32_MASK << SK_R32_SHIFT; + uint32_t gmask = SK_G32_MASK << SK_G32_SHIFT; + uint32_t bmask = SK_B32_MASK << SK_B32_SHIFT; + uint32_t amask = SK_A32_MASK << SK_A32_SHIFT; + + if (fScreen->flags & SDL_OPENGL) { + fSurface = NULL; + fGLCanvas = new SkGLCanvas; + fGLCanvas->setViewport(fScreen->w, fScreen->h); + } else { + fGLCanvas = NULL; + fSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, fScreen->w, fScreen->h, + 32, rmask, gmask, bmask, amask); + } +} + +SkOSWindow::~SkOSWindow() { + delete fGLCanvas; + if (fSurface) { + SDL_FreeSurface(fSurface); + } +} + +#include + +void SkOSWindow::doDraw() { + if (fGLCanvas) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); + glEnable(GL_TEXTURE_2D); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + int count = fGLCanvas->save(); + this->draw(fGLCanvas); + fGLCanvas->restoreToCount(count); + SDL_GL_SwapBuffers( ); + } else { + if ( SDL_MUSTLOCK(fSurface) ) { + if ( SDL_LockSurface(fSurface) < 0 ) { + return; + } + } + + SkBitmap bitmap; + + if (skia_setBitmapFromSurface(&bitmap, fSurface)) { + SkCanvas canvas(bitmap); + this->draw(&canvas); + } + + if ( SDL_MUSTLOCK(fSurface) ) { + SDL_UnlockSurface(fSurface); + } + + int result = SDL_BlitSurface(fSurface, NULL, fScreen, NULL); + if (result) { + SkDebugf("------- SDL_BlitSurface returned %d\n", result); + } + SDL_UpdateRect(fScreen, 0, 0, fScreen->w, fScreen->h); + } +} + +static SkKey find_skkey(SDLKey src) { + // this array must match the enum order in SkKey.h + static const SDLKey gKeys[] = { + SDLK_UNKNOWN, + SDLK_UNKNOWN, // left softkey + SDLK_UNKNOWN, // right softkey + SDLK_UNKNOWN, // home + SDLK_UNKNOWN, // back + SDLK_UNKNOWN, // send + SDLK_UNKNOWN, // end + SDLK_0, + SDLK_1, + SDLK_2, + SDLK_3, + SDLK_4, + SDLK_5, + SDLK_6, + SDLK_7, + SDLK_8, + SDLK_9, + SDLK_ASTERISK, + SDLK_HASH, + SDLK_UP, + SDLK_DOWN, + SDLK_LEFT, + SDLK_RIGHT, + SDLK_RETURN, // OK + SDLK_UNKNOWN, // volume up + SDLK_UNKNOWN, // volume down + SDLK_UNKNOWN, // power + SDLK_UNKNOWN, // camera + }; + + const SDLKey* array = gKeys; + for (size_t i = 0; i < SK_ARRAY_COUNT(gKeys); i++) { + if (array[i] == src) { + return static_cast(i); + } + } + return kNONE_SkKey; +} + +void SkOSWindow::handleSDLEvent(const SDL_Event& event) { + switch (event.type) { + case SDL_VIDEORESIZE: + this->resize(event.resize.w, event.resize.h); + break; + case SDL_VIDEOEXPOSE: + this->doDraw(); + break; + case SDL_MOUSEMOTION: + if (event.motion.state == SDL_PRESSED) { + this->handleClick(event.motion.x, event.motion.y, + SkView::Click::kMoved_State); + } + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + this->handleClick(event.button.x, event.button.y, + event.button.state == SDL_PRESSED ? + SkView::Click::kDown_State : + SkView::Click::kUp_State); + break; + case SDL_KEYDOWN: { + SkKey sk = find_skkey(event.key.keysym.sym); + if (kNONE_SkKey != sk) { + if (event.key.state == SDL_PRESSED) { + this->handleKey(sk); + } else { + this->handleKeyUp(sk); + } + } + break; + } + case SDL_USEREVENT: + if (SkEvent::ProcessEvent()) { + post_SkEvent_event(); + } + break; + } +} + +void SkOSWindow::onHandleInval(const SkIRect& r) { + SDL_Event evt; + evt.type = SDL_VIDEOEXPOSE; + evt.expose.type = SDL_VIDEOEXPOSE; + SDL_PushEvent(&evt); +} + +void SkOSWindow::onSetTitle(const char title[]) { + SDL_WM_SetCaption(title, NULL); +} + +void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu) {} + +/////////////////////////////////////////////////////////////////////////////////////// + +void SkEvent::SignalNonEmptyQueue() { + SkDebugf("-------- signal nonempty\n"); + post_SkEvent_event(); +} + +static Uint32 timer_callback(Uint32 interval) { +// SkDebugf("-------- timercallback %d\n", interval); + SkEvent::ServiceQueueTimer(); + return 0; +} + +void SkEvent::SignalQueueTimer(SkMSec delay) +{ + SDL_SetTimer(0, NULL); + if (delay) { + SDL_SetTimer(delay, timer_callback); + } +}