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