blob: b6b6882368ce43b0fd4b1e37411204c6b072a524 [file] [log] [blame]
reed@android.com671cd652009-05-22 20:44:12 +00001#include "SkOSWindow_SDL.h"
2#include "SkCanvas.h"
reed@android.comc3a8c5f2009-05-26 13:27:48 +00003#include "SkColorPriv.h"
reed@android.com25fc5b92009-05-29 03:40:05 +00004#include "SkGLCanvas.h"
reed@android.com671cd652009-05-22 20:44:12 +00005#include "SkOSMenu.h"
6#include "SkTime.h"
7
8static void post_SkEvent_event() {
9 SDL_Event evt;
10 evt.type = SDL_USEREVENT;
11 evt.user.type = SDL_USEREVENT;
12 evt.user.code = 0;
13 evt.user.data1 = NULL;
14 evt.user.data2 = NULL;
15 SDL_PushEvent(&evt);
16}
17
18static bool skia_setBitmapFromSurface(SkBitmap* dst, SDL_Surface* src) {
19 SkBitmap::Config config;
20
21 switch (src->format->BytesPerPixel) {
22 case 2:
23 config = SkBitmap::kRGB_565_Config;
24 break;
25 case 4:
26 config = SkBitmap::kARGB_8888_Config;
27 break;
28 default:
29 return false;
30 }
31
32 dst->setConfig(config, src->w, src->h, src->pitch);
33 dst->setPixels(src->pixels);
34 return true;
35}
36
reed@android.comc3a8c5f2009-05-26 13:27:48 +000037SkOSWindow::SkOSWindow(void* screen) {
38 fScreen = reinterpret_cast<SDL_Surface*>(screen);
39 this->resize(fScreen->w, fScreen->h);
40
41 uint32_t rmask = SK_R32_MASK << SK_R32_SHIFT;
42 uint32_t gmask = SK_G32_MASK << SK_G32_SHIFT;
43 uint32_t bmask = SK_B32_MASK << SK_B32_SHIFT;
44 uint32_t amask = SK_A32_MASK << SK_A32_SHIFT;
45
reed@android.com25fc5b92009-05-29 03:40:05 +000046 if (fScreen->flags & SDL_OPENGL) {
47 fSurface = NULL;
48 fGLCanvas = new SkGLCanvas;
49 fGLCanvas->setViewport(fScreen->w, fScreen->h);
50 } else {
51 fGLCanvas = NULL;
52 fSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, fScreen->w, fScreen->h,
53 32, rmask, gmask, bmask, amask);
54 }
reed@android.comc3a8c5f2009-05-26 13:27:48 +000055}
56
57SkOSWindow::~SkOSWindow() {
reed@android.com25fc5b92009-05-29 03:40:05 +000058 delete fGLCanvas;
59 if (fSurface) {
60 SDL_FreeSurface(fSurface);
61 }
reed@android.com671cd652009-05-22 20:44:12 +000062}
63
reed@android.com25fc5b92009-05-29 03:40:05 +000064#include <OpenGL/gl.h>
65
reed@android.com671cd652009-05-22 20:44:12 +000066void SkOSWindow::doDraw() {
reed@android.com25fc5b92009-05-29 03:40:05 +000067 if (fGLCanvas) {
68 glEnable(GL_BLEND);
69 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
70 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
71 glEnable(GL_TEXTURE_2D);
72 glClearColor(0, 0, 0, 0);
73 glClear(GL_COLOR_BUFFER_BIT);
74
75 int count = fGLCanvas->save();
76 this->draw(fGLCanvas);
77 fGLCanvas->restoreToCount(count);
78 SDL_GL_SwapBuffers( );
79 } else {
80 if ( SDL_MUSTLOCK(fSurface) ) {
81 if ( SDL_LockSurface(fSurface) < 0 ) {
82 return;
83 }
reed@android.com671cd652009-05-22 20:44:12 +000084 }
reed@android.com671cd652009-05-22 20:44:12 +000085
reed@android.com25fc5b92009-05-29 03:40:05 +000086 SkBitmap bitmap;
reed@android.com671cd652009-05-22 20:44:12 +000087
reed@android.com25fc5b92009-05-29 03:40:05 +000088 if (skia_setBitmapFromSurface(&bitmap, fSurface)) {
89 SkCanvas canvas(bitmap);
90 this->draw(&canvas);
91 }
reed@android.com671cd652009-05-22 20:44:12 +000092
reed@android.com25fc5b92009-05-29 03:40:05 +000093 if ( SDL_MUSTLOCK(fSurface) ) {
94 SDL_UnlockSurface(fSurface);
95 }
reed@android.comc3a8c5f2009-05-26 13:27:48 +000096
reed@android.com25fc5b92009-05-29 03:40:05 +000097 int result = SDL_BlitSurface(fSurface, NULL, fScreen, NULL);
98 if (result) {
99 SkDebugf("------- SDL_BlitSurface returned %d\n", result);
100 }
101 SDL_UpdateRect(fScreen, 0, 0, fScreen->w, fScreen->h);
reed@android.comc3a8c5f2009-05-26 13:27:48 +0000102 }
reed@android.com671cd652009-05-22 20:44:12 +0000103}
104
105static SkKey find_skkey(SDLKey src) {
106 // this array must match the enum order in SkKey.h
107 static const SDLKey gKeys[] = {
108 SDLK_UNKNOWN,
109 SDLK_UNKNOWN, // left softkey
110 SDLK_UNKNOWN, // right softkey
111 SDLK_UNKNOWN, // home
112 SDLK_UNKNOWN, // back
113 SDLK_UNKNOWN, // send
114 SDLK_UNKNOWN, // end
115 SDLK_0,
116 SDLK_1,
117 SDLK_2,
118 SDLK_3,
119 SDLK_4,
120 SDLK_5,
121 SDLK_6,
122 SDLK_7,
123 SDLK_8,
124 SDLK_9,
125 SDLK_ASTERISK,
126 SDLK_HASH,
127 SDLK_UP,
128 SDLK_DOWN,
129 SDLK_LEFT,
130 SDLK_RIGHT,
131 SDLK_RETURN, // OK
132 SDLK_UNKNOWN, // volume up
133 SDLK_UNKNOWN, // volume down
134 SDLK_UNKNOWN, // power
135 SDLK_UNKNOWN, // camera
136 };
137
138 const SDLKey* array = gKeys;
139 for (size_t i = 0; i < SK_ARRAY_COUNT(gKeys); i++) {
140 if (array[i] == src) {
141 return static_cast<SkKey>(i);
142 }
143 }
144 return kNONE_SkKey;
145}
146
147void SkOSWindow::handleSDLEvent(const SDL_Event& event) {
148 switch (event.type) {
149 case SDL_VIDEORESIZE:
150 this->resize(event.resize.w, event.resize.h);
151 break;
152 case SDL_VIDEOEXPOSE:
153 this->doDraw();
154 break;
155 case SDL_MOUSEMOTION:
156 if (event.motion.state == SDL_PRESSED) {
157 this->handleClick(event.motion.x, event.motion.y,
158 SkView::Click::kMoved_State);
159 }
160 break;
161 case SDL_MOUSEBUTTONDOWN:
162 case SDL_MOUSEBUTTONUP:
163 this->handleClick(event.button.x, event.button.y,
164 event.button.state == SDL_PRESSED ?
165 SkView::Click::kDown_State :
166 SkView::Click::kUp_State);
167 break;
168 case SDL_KEYDOWN: {
169 SkKey sk = find_skkey(event.key.keysym.sym);
170 if (kNONE_SkKey != sk) {
171 if (event.key.state == SDL_PRESSED) {
172 this->handleKey(sk);
173 } else {
174 this->handleKeyUp(sk);
175 }
176 }
177 break;
178 }
179 case SDL_USEREVENT:
180 if (SkEvent::ProcessEvent()) {
181 post_SkEvent_event();
182 }
183 break;
184 }
185}
186
187void SkOSWindow::onHandleInval(const SkIRect& r) {
188 SDL_Event evt;
189 evt.type = SDL_VIDEOEXPOSE;
190 evt.expose.type = SDL_VIDEOEXPOSE;
191 SDL_PushEvent(&evt);
192}
193
194void SkOSWindow::onSetTitle(const char title[]) {
195 SDL_WM_SetCaption(title, NULL);
196}
197
198void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu) {}
199
200///////////////////////////////////////////////////////////////////////////////////////
201
202void SkEvent::SignalNonEmptyQueue() {
203 SkDebugf("-------- signal nonempty\n");
204 post_SkEvent_event();
205}
206
207static Uint32 timer_callback(Uint32 interval) {
208// SkDebugf("-------- timercallback %d\n", interval);
209 SkEvent::ServiceQueueTimer();
210 return 0;
211}
212
213void SkEvent::SignalQueueTimer(SkMSec delay)
214{
215 SDL_SetTimer(0, NULL);
216 if (delay) {
217 SDL_SetTimer(delay, timer_callback);
218 }
219}
220