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