1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8671cd656785de5e84564b6ffe4831625d7016dedreed@android.com#include "SkOSWindow_SDL.h" 9671cd656785de5e84564b6ffe4831625d7016dedreed@android.com#include "SkCanvas.h" 10c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com#include "SkColorPriv.h" 1125fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com#include "SkGLCanvas.h" 12671cd656785de5e84564b6ffe4831625d7016dedreed@android.com#include "SkOSMenu.h" 13671cd656785de5e84564b6ffe4831625d7016dedreed@android.com#include "SkTime.h" 14671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 15671cd656785de5e84564b6ffe4831625d7016dedreed@android.comstatic void post_SkEvent_event() { 16671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDL_Event evt; 17671cd656785de5e84564b6ffe4831625d7016dedreed@android.com evt.type = SDL_USEREVENT; 18671cd656785de5e84564b6ffe4831625d7016dedreed@android.com evt.user.type = SDL_USEREVENT; 19671cd656785de5e84564b6ffe4831625d7016dedreed@android.com evt.user.code = 0; 20671cd656785de5e84564b6ffe4831625d7016dedreed@android.com evt.user.data1 = NULL; 21671cd656785de5e84564b6ffe4831625d7016dedreed@android.com evt.user.data2 = NULL; 22671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDL_PushEvent(&evt); 23671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 24671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 25671cd656785de5e84564b6ffe4831625d7016dedreed@android.comstatic bool skia_setBitmapFromSurface(SkBitmap* dst, SDL_Surface* src) { 26a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org SkColorType ct; 27a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org SkAlphaType at; 28d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 29671cd656785de5e84564b6ffe4831625d7016dedreed@android.com switch (src->format->BytesPerPixel) { 30671cd656785de5e84564b6ffe4831625d7016dedreed@android.com case 2: 31a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org ct = kRGB_565_SkColorType; 32a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org at = kOpaque_SkAlphaType; 33671cd656785de5e84564b6ffe4831625d7016dedreed@android.com break; 34671cd656785de5e84564b6ffe4831625d7016dedreed@android.com case 4: 35a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org ct = kN32_SkColorType; 36a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org at = kPremul_SkAlphaType; 37671cd656785de5e84564b6ffe4831625d7016dedreed@android.com break; 38671cd656785de5e84564b6ffe4831625d7016dedreed@android.com default: 39671cd656785de5e84564b6ffe4831625d7016dedreed@android.com return false; 40671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 41d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 42a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org return dst->installPixels(SkImageInfo::Make(src->w, src->h, ct, at), src->pixels, src->pitch); 43671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 44671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 45c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.comSkOSWindow::SkOSWindow(void* screen) { 46c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com fScreen = reinterpret_cast<SDL_Surface*>(screen); 47c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com this->resize(fScreen->w, fScreen->h); 48d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 49c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com uint32_t rmask = SK_R32_MASK << SK_R32_SHIFT; 50c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com uint32_t gmask = SK_G32_MASK << SK_G32_SHIFT; 51c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com uint32_t bmask = SK_B32_MASK << SK_B32_SHIFT; 52c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com uint32_t amask = SK_A32_MASK << SK_A32_SHIFT; 53c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com 5425fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com if (fScreen->flags & SDL_OPENGL) { 5525fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com fSurface = NULL; 5625fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com fGLCanvas = new SkGLCanvas; 5725fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com fGLCanvas->setViewport(fScreen->w, fScreen->h); 5825fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com } else { 5925fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com fGLCanvas = NULL; 6025fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com fSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, fScreen->w, fScreen->h, 6125fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com 32, rmask, gmask, bmask, amask); 6225fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com } 63c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com} 64c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com 65c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.comSkOSWindow::~SkOSWindow() { 6625fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com delete fGLCanvas; 6725fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com if (fSurface) { 6825fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com SDL_FreeSurface(fSurface); 6925fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com } 70671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 71671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 7225fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com#include <OpenGL/gl.h> 7325fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com 74671cd656785de5e84564b6ffe4831625d7016dedreed@android.comvoid SkOSWindow::doDraw() { 7525fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com if (fGLCanvas) { 7625fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com glEnable(GL_BLEND); 7725fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 7825fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); 7925fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com glEnable(GL_TEXTURE_2D); 8025fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com glClearColor(0, 0, 0, 0); 8125fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com glClear(GL_COLOR_BUFFER_BIT); 8225fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com 8325fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com int count = fGLCanvas->save(); 8425fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com this->draw(fGLCanvas); 8525fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com fGLCanvas->restoreToCount(count); 8625fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com SDL_GL_SwapBuffers( ); 8725fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com } else { 8825fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com if ( SDL_MUSTLOCK(fSurface) ) { 8925fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com if ( SDL_LockSurface(fSurface) < 0 ) { 9025fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com return; 9125fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com } 92671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 93671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 9425fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com SkBitmap bitmap; 95671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 9625fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com if (skia_setBitmapFromSurface(&bitmap, fSurface)) { 9725fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com SkCanvas canvas(bitmap); 9825fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com this->draw(&canvas); 9925fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com } 100671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 10125fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com if ( SDL_MUSTLOCK(fSurface) ) { 10225fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com SDL_UnlockSurface(fSurface); 10325fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com } 104c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com 10525fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com int result = SDL_BlitSurface(fSurface, NULL, fScreen, NULL); 10625fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com if (result) { 10725fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com SkDebugf("------- SDL_BlitSurface returned %d\n", result); 10825fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com } 10925fc5b9f0a1b9aee9d141cba027aa5a14a0df762reed@android.com SDL_UpdateRect(fScreen, 0, 0, fScreen->w, fScreen->h); 110c3a8c5fb385dca5c57f8002e5331360f21c1a61freed@android.com } 111671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 112671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 113671cd656785de5e84564b6ffe4831625d7016dedreed@android.comstatic SkKey find_skkey(SDLKey src) { 114671cd656785de5e84564b6ffe4831625d7016dedreed@android.com // this array must match the enum order in SkKey.h 115671cd656785de5e84564b6ffe4831625d7016dedreed@android.com static const SDLKey gKeys[] = { 116671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, 117671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, // left softkey 118671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, // right softkey 119671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, // home 120671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, // back 121671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, // send 122671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, // end 123671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_0, 124671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_1, 125671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_2, 126671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_3, 127671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_4, 128671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_5, 129671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_6, 130671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_7, 131671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_8, 132671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_9, 133671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_ASTERISK, 134671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_HASH, 135671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UP, 136671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_DOWN, 137671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_LEFT, 138671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_RIGHT, 139671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_RETURN, // OK 140671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, // volume up 141671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, // volume down 142671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, // power 143671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDLK_UNKNOWN, // camera 144671cd656785de5e84564b6ffe4831625d7016dedreed@android.com }; 145d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 146671cd656785de5e84564b6ffe4831625d7016dedreed@android.com const SDLKey* array = gKeys; 147671cd656785de5e84564b6ffe4831625d7016dedreed@android.com for (size_t i = 0; i < SK_ARRAY_COUNT(gKeys); i++) { 148671cd656785de5e84564b6ffe4831625d7016dedreed@android.com if (array[i] == src) { 149671cd656785de5e84564b6ffe4831625d7016dedreed@android.com return static_cast<SkKey>(i); 150671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 151671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 152671cd656785de5e84564b6ffe4831625d7016dedreed@android.com return kNONE_SkKey; 153671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 154671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 155671cd656785de5e84564b6ffe4831625d7016dedreed@android.comvoid SkOSWindow::handleSDLEvent(const SDL_Event& event) { 156671cd656785de5e84564b6ffe4831625d7016dedreed@android.com switch (event.type) { 157671cd656785de5e84564b6ffe4831625d7016dedreed@android.com case SDL_VIDEORESIZE: 158671cd656785de5e84564b6ffe4831625d7016dedreed@android.com this->resize(event.resize.w, event.resize.h); 159671cd656785de5e84564b6ffe4831625d7016dedreed@android.com break; 160671cd656785de5e84564b6ffe4831625d7016dedreed@android.com case SDL_VIDEOEXPOSE: 161671cd656785de5e84564b6ffe4831625d7016dedreed@android.com this->doDraw(); 162671cd656785de5e84564b6ffe4831625d7016dedreed@android.com break; 163671cd656785de5e84564b6ffe4831625d7016dedreed@android.com case SDL_MOUSEMOTION: 164671cd656785de5e84564b6ffe4831625d7016dedreed@android.com if (event.motion.state == SDL_PRESSED) { 165671cd656785de5e84564b6ffe4831625d7016dedreed@android.com this->handleClick(event.motion.x, event.motion.y, 166671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SkView::Click::kMoved_State); 167671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 168671cd656785de5e84564b6ffe4831625d7016dedreed@android.com break; 169671cd656785de5e84564b6ffe4831625d7016dedreed@android.com case SDL_MOUSEBUTTONDOWN: 170671cd656785de5e84564b6ffe4831625d7016dedreed@android.com case SDL_MOUSEBUTTONUP: 171671cd656785de5e84564b6ffe4831625d7016dedreed@android.com this->handleClick(event.button.x, event.button.y, 172671cd656785de5e84564b6ffe4831625d7016dedreed@android.com event.button.state == SDL_PRESSED ? 173671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SkView::Click::kDown_State : 174671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SkView::Click::kUp_State); 175671cd656785de5e84564b6ffe4831625d7016dedreed@android.com break; 176671cd656785de5e84564b6ffe4831625d7016dedreed@android.com case SDL_KEYDOWN: { 177671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SkKey sk = find_skkey(event.key.keysym.sym); 178671cd656785de5e84564b6ffe4831625d7016dedreed@android.com if (kNONE_SkKey != sk) { 179671cd656785de5e84564b6ffe4831625d7016dedreed@android.com if (event.key.state == SDL_PRESSED) { 180671cd656785de5e84564b6ffe4831625d7016dedreed@android.com this->handleKey(sk); 181671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } else { 182671cd656785de5e84564b6ffe4831625d7016dedreed@android.com this->handleKeyUp(sk); 183671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 184671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 185671cd656785de5e84564b6ffe4831625d7016dedreed@android.com break; 186671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 187671cd656785de5e84564b6ffe4831625d7016dedreed@android.com case SDL_USEREVENT: 188671cd656785de5e84564b6ffe4831625d7016dedreed@android.com if (SkEvent::ProcessEvent()) { 189671cd656785de5e84564b6ffe4831625d7016dedreed@android.com post_SkEvent_event(); 190671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 191671cd656785de5e84564b6ffe4831625d7016dedreed@android.com break; 192671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 193671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 194671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 195671cd656785de5e84564b6ffe4831625d7016dedreed@android.comvoid SkOSWindow::onHandleInval(const SkIRect& r) { 196671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDL_Event evt; 197671cd656785de5e84564b6ffe4831625d7016dedreed@android.com evt.type = SDL_VIDEOEXPOSE; 198671cd656785de5e84564b6ffe4831625d7016dedreed@android.com evt.expose.type = SDL_VIDEOEXPOSE; 199671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDL_PushEvent(&evt); 200671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 201671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 202671cd656785de5e84564b6ffe4831625d7016dedreed@android.comvoid SkOSWindow::onSetTitle(const char title[]) { 203671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDL_WM_SetCaption(title, NULL); 204671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 205671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 206671cd656785de5e84564b6ffe4831625d7016dedreed@android.comvoid SkOSWindow::onAddMenu(const SkOSMenu* sk_menu) {} 207671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 208671cd656785de5e84564b6ffe4831625d7016dedreed@android.com/////////////////////////////////////////////////////////////////////////////////////// 209671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 210671cd656785de5e84564b6ffe4831625d7016dedreed@android.comvoid SkEvent::SignalNonEmptyQueue() { 211671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SkDebugf("-------- signal nonempty\n"); 212671cd656785de5e84564b6ffe4831625d7016dedreed@android.com post_SkEvent_event(); 213671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 214671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 215671cd656785de5e84564b6ffe4831625d7016dedreed@android.comstatic Uint32 timer_callback(Uint32 interval) { 216671cd656785de5e84564b6ffe4831625d7016dedreed@android.com// SkDebugf("-------- timercallback %d\n", interval); 217d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkEvent::ServiceQueueTimer(); 218671cd656785de5e84564b6ffe4831625d7016dedreed@android.com return 0; 219671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 220671cd656785de5e84564b6ffe4831625d7016dedreed@android.com 221671cd656785de5e84564b6ffe4831625d7016dedreed@android.comvoid SkEvent::SignalQueueTimer(SkMSec delay) 222671cd656785de5e84564b6ffe4831625d7016dedreed@android.com{ 223671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDL_SetTimer(0, NULL); 224671cd656785de5e84564b6ffe4831625d7016dedreed@android.com if (delay) { 225671cd656785de5e84564b6ffe4831625d7016dedreed@android.com SDL_SetTimer(delay, timer_callback); 226671cd656785de5e84564b6ffe4831625d7016dedreed@android.com } 227671cd656785de5e84564b6ffe4831625d7016dedreed@android.com} 228