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