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