• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
post_SkEvent_event()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 
skia_setBitmapFromSurface(SkBitmap * dst,SDL_Surface * src)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 
SkOSWindow(void * screen)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 
~SkOSWindow()64 SkOSWindow::~SkOSWindow() {
65     delete fGLCanvas;
66     if (fSurface) {
67         SDL_FreeSurface(fSurface);
68     }
69 }
70 
71 #include <OpenGL/gl.h>
72 
doDraw()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 
find_skkey(SDLKey src)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 
handleSDLEvent(const SDL_Event & event)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 
onHandleInval(const SkIRect & r)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 
onSetTitle(const char title[])201 void SkOSWindow::onSetTitle(const char title[]) {
202     SDL_WM_SetCaption(title, NULL);
203 }
204 
onAddMenu(const SkOSMenu * sk_menu)205 void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu) {}
206 
207 ///////////////////////////////////////////////////////////////////////////////////////
208 
SignalNonEmptyQueue()209 void SkEvent::SignalNonEmptyQueue() {
210     SkDebugf("-------- signal nonempty\n");
211     post_SkEvent_event();
212 }
213 
timer_callback(Uint32 interval)214 static Uint32 timer_callback(Uint32 interval) {
215 //    SkDebugf("-------- timercallback %d\n", interval);
216     SkEvent::ServiceQueueTimer();
217     return 0;
218 }
219 
SignalQueueTimer(SkMSec delay)220 void SkEvent::SignalQueueTimer(SkMSec delay)
221 {
222     SDL_SetTimer(0, NULL);
223     if (delay) {
224         SDL_SetTimer(delay, timer_callback);
225     }
226 }
227