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