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