Home | History | Annotate | Download | only in sdl
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "SkOSWindow_SDL.h"
      9 #include "SkCanvas.h"
     10 #include "SkColorPriv.h"
     11 #include "SkGLCanvas.h"
     12 #include "SkOSMenu.h"
     13 #include "SkTime.h"
     14 
     15 static void post_SkEvent_event() {
     16     SDL_Event evt;
     17     evt.type = SDL_USEREVENT;
     18     evt.user.type = SDL_USEREVENT;
     19     evt.user.code = 0;
     20     evt.user.data1 = NULL;
     21     evt.user.data2 = NULL;
     22     SDL_PushEvent(&evt);
     23 }
     24 
     25 static bool skia_setBitmapFromSurface(SkBitmap* dst, SDL_Surface* src) {
     26     SkBitmap::Config config;
     27 
     28     switch (src->format->BytesPerPixel) {
     29         case 2:
     30             config = SkBitmap::kRGB_565_Config;
     31             break;
     32         case 4:
     33             config = SkBitmap::kARGB_8888_Config;
     34             break;
     35         default:
     36             return false;
     37     }
     38 
     39     dst->setConfig(config, src->w, src->h, src->pitch);
     40     dst->setPixels(src->pixels);
     41     return true;
     42 }
     43 
     44 SkOSWindow::SkOSWindow(void* screen) {
     45     fScreen = reinterpret_cast<SDL_Surface*>(screen);
     46     this->resize(fScreen->w, fScreen->h);
     47 
     48     uint32_t rmask = SK_R32_MASK << SK_R32_SHIFT;
     49     uint32_t gmask = SK_G32_MASK << SK_G32_SHIFT;
     50     uint32_t bmask = SK_B32_MASK << SK_B32_SHIFT;
     51     uint32_t amask = SK_A32_MASK << SK_A32_SHIFT;
     52 
     53     if (fScreen->flags & SDL_OPENGL) {
     54         fSurface = NULL;
     55         fGLCanvas = new SkGLCanvas;
     56         fGLCanvas->setViewport(fScreen->w, fScreen->h);
     57     } else {
     58         fGLCanvas = NULL;
     59         fSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, fScreen->w, fScreen->h,
     60                                         32, rmask, gmask, bmask, amask);
     61     }
     62 }
     63 
     64 SkOSWindow::~SkOSWindow() {
     65     delete fGLCanvas;
     66     if (fSurface) {
     67         SDL_FreeSurface(fSurface);
     68     }
     69 }
     70 
     71 #include <OpenGL/gl.h>
     72 
     73 void SkOSWindow::doDraw() {
     74     if (fGLCanvas) {
     75         glEnable(GL_BLEND);
     76         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     77         glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
     78         glEnable(GL_TEXTURE_2D);
     79         glClearColor(0, 0, 0, 0);
     80         glClear(GL_COLOR_BUFFER_BIT);
     81 
     82         int count = fGLCanvas->save();
     83         this->draw(fGLCanvas);
     84         fGLCanvas->restoreToCount(count);
     85         SDL_GL_SwapBuffers( );
     86     } else {
     87         if ( SDL_MUSTLOCK(fSurface) ) {
     88             if ( SDL_LockSurface(fSurface) < 0 ) {
     89                 return;
     90             }
     91         }
     92 
     93         SkBitmap bitmap;
     94 
     95         if (skia_setBitmapFromSurface(&bitmap, fSurface)) {
     96             SkCanvas canvas(bitmap);
     97             this->draw(&canvas);
     98         }
     99 
    100         if ( SDL_MUSTLOCK(fSurface) ) {
    101             SDL_UnlockSurface(fSurface);
    102         }
    103 
    104         int result = SDL_BlitSurface(fSurface, NULL, fScreen, NULL);
    105         if (result) {
    106             SkDebugf("------- SDL_BlitSurface returned %d\n", result);
    107         }
    108         SDL_UpdateRect(fScreen, 0, 0, fScreen->w, fScreen->h);
    109     }
    110 }
    111 
    112 static SkKey find_skkey(SDLKey src) {
    113     // this array must match the enum order in SkKey.h
    114     static const SDLKey gKeys[] = {
    115         SDLK_UNKNOWN,
    116         SDLK_UNKNOWN,   // left softkey
    117         SDLK_UNKNOWN,   // right softkey
    118         SDLK_UNKNOWN,   // home
    119         SDLK_UNKNOWN,   // back
    120         SDLK_UNKNOWN,   // send
    121         SDLK_UNKNOWN,   // end
    122         SDLK_0,
    123         SDLK_1,
    124         SDLK_2,
    125         SDLK_3,
    126         SDLK_4,
    127         SDLK_5,
    128         SDLK_6,
    129         SDLK_7,
    130         SDLK_8,
    131         SDLK_9,
    132         SDLK_ASTERISK,
    133         SDLK_HASH,
    134         SDLK_UP,
    135         SDLK_DOWN,
    136         SDLK_LEFT,
    137         SDLK_RIGHT,
    138         SDLK_RETURN,    // OK
    139         SDLK_UNKNOWN,   // volume up
    140         SDLK_UNKNOWN,   // volume down
    141         SDLK_UNKNOWN,   // power
    142         SDLK_UNKNOWN,   // camera
    143     };
    144 
    145     const SDLKey* array = gKeys;
    146     for (size_t i = 0; i < SK_ARRAY_COUNT(gKeys); i++) {
    147         if (array[i] == src) {
    148             return static_cast<SkKey>(i);
    149         }
    150     }
    151     return kNONE_SkKey;
    152 }
    153 
    154 void SkOSWindow::handleSDLEvent(const SDL_Event& event) {
    155     switch (event.type) {
    156         case SDL_VIDEORESIZE:
    157             this->resize(event.resize.w, event.resize.h);
    158             break;
    159         case SDL_VIDEOEXPOSE:
    160             this->doDraw();
    161             break;
    162         case SDL_MOUSEMOTION:
    163             if (event.motion.state == SDL_PRESSED) {
    164                 this->handleClick(event.motion.x, event.motion.y,
    165                                    SkView::Click::kMoved_State);
    166             }
    167             break;
    168         case SDL_MOUSEBUTTONDOWN:
    169         case SDL_MOUSEBUTTONUP:
    170             this->handleClick(event.button.x, event.button.y,
    171                                event.button.state == SDL_PRESSED ?
    172                                SkView::Click::kDown_State :
    173                                SkView::Click::kUp_State);
    174             break;
    175         case SDL_KEYDOWN: {
    176             SkKey sk = find_skkey(event.key.keysym.sym);
    177             if (kNONE_SkKey != sk) {
    178                 if (event.key.state == SDL_PRESSED) {
    179                     this->handleKey(sk);
    180                 } else {
    181                     this->handleKeyUp(sk);
    182                 }
    183             }
    184             break;
    185         }
    186         case SDL_USEREVENT:
    187             if (SkEvent::ProcessEvent()) {
    188                 post_SkEvent_event();
    189             }
    190             break;
    191     }
    192 }
    193 
    194 void SkOSWindow::onHandleInval(const SkIRect& r) {
    195     SDL_Event evt;
    196     evt.type = SDL_VIDEOEXPOSE;
    197     evt.expose.type = SDL_VIDEOEXPOSE;
    198     SDL_PushEvent(&evt);
    199 }
    200 
    201 void SkOSWindow::onSetTitle(const char title[]) {
    202     SDL_WM_SetCaption(title, NULL);
    203 }
    204 
    205 void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu) {}
    206 
    207 ///////////////////////////////////////////////////////////////////////////////////////
    208 
    209 void SkEvent::SignalNonEmptyQueue() {
    210     SkDebugf("-------- signal nonempty\n");
    211     post_SkEvent_event();
    212 }
    213 
    214 static Uint32 timer_callback(Uint32 interval) {
    215 //    SkDebugf("-------- timercallback %d\n", interval);
    216     SkEvent::ServiceQueueTimer();
    217     return 0;
    218 }
    219 
    220 void SkEvent::SignalQueueTimer(SkMSec delay)
    221 {
    222     SDL_SetTimer(0, NULL);
    223     if (delay) {
    224         SDL_SetTimer(delay, timer_callback);
    225     }
    226 }
    227