blob: 80802a1dd09f8d3f6084397f12f19fbfd41e28b4 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
reed@android.com671cd652009-05-22 20:44:12 +00007#include "SkOSWindow_SDL.h"
8#include "SkCanvas.h"
reed@android.com671cd652009-05-22 20:44:12 +00009
joshualitta4d37972015-11-05 08:35:31 -080010#if defined(SK_BUILD_FOR_ANDROID)
11#include <GLES/gl.h>
12#else
joshualitt65d6fbb2015-11-04 13:41:02 -080013#include <GL/gl.h>
joshualitta4d37972015-11-05 08:35:31 -080014#endif
joshualitt65d6fbb2015-11-04 13:41:02 -080015
16const int SCREEN_WIDTH = 640;
17const int SCREEN_HEIGHT = 480;
18
19static void handle_error() {
20 const char* error = SDL_GetError();
21 SkDebugf("SDL Error: %s\n", error);
22 SDL_ClearError();
reed@android.com671cd652009-05-22 20:44:12 +000023}
24
joshualitt65d6fbb2015-11-04 13:41:02 -080025SkOSWindow::SkOSWindow(void* screen) : fQuit(false) , fGLContext(nullptr) {
joshualitta4d37972015-11-05 08:35:31 -080026#if defined(SK_BUILD_FOR_ANDROID)
27 // TODO we should try and get a 3.0 context first
28 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
29 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
30 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
31 fWindowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE |
32 SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN_DESKTOP |
33 SDL_WINDOW_ALLOW_HIGHDPI;
34#else
35 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
36 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
37 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
38 SDL_StartTextInput();
39
40 fWindowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
41#endif
42 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
43 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
44 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
45 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
46 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
47 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
48
49 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
50
51 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
52 handle_error();
53 return;
54 }
55
56 SDL_DisplayMode dm;
57 if (SDL_GetDesktopDisplayMode(0, &dm) != 0) {
58 handle_error();
59 return;
60 }
61
62 fWindow = SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
63 dm.w, dm.h, fWindowFlags);
64
joshualitt65d6fbb2015-11-04 13:41:02 -080065 if (!fWindow) {
66 handle_error();
67 return;
reed@android.com671cd652009-05-22 20:44:12 +000068 }
joshualitta4d37972015-11-05 08:35:31 -080069 this->resize(SkIntToScalar(dm.w), SkIntToScalar(dm.h));
reed@android.comc3a8c5f2009-05-26 13:27:48 +000070}
71
72SkOSWindow::~SkOSWindow() {
joshualitt65d6fbb2015-11-04 13:41:02 -080073 if (fGLContext) {
74 SDL_GL_DeleteContext(fGLContext);
75 }
76
77 //Destroy window
78 SDL_DestroyWindow(fWindow);
79
80 //Quit SDL subsystems
81 SDL_Quit();
82}
83
84void SkOSWindow::detach() {
85 if (fGLContext) {
86 SDL_GL_DeleteContext(fGLContext);
87 fGLContext = nullptr;
reed@android.com25fc5b92009-05-29 03:40:05 +000088 }
joshualitta4d37972015-11-05 08:35:31 -080089
90#if defined(SK_BUILD_FOR_ANDROID)
91 if (fWindow) {
92 // Destroy window
93 // Not totally sure why, but we have to do this or swapbuffers will hang
94 SDL_DestroyWindow(fWindow);
95 fWindow = nullptr;
96 }
97#endif
reed@android.com671cd652009-05-22 20:44:12 +000098}
99
joshualitta4d37972015-11-05 08:35:31 -0800100bool SkOSWindow::attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo* info) {
101 if (!fWindow) {
102 fWindow = SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
103 SCREEN_WIDTH, SCREEN_HEIGHT,
104 fWindowFlags);
105 }
reed@android.com25fc5b92009-05-29 03:40:05 +0000106
joshualitt65d6fbb2015-11-04 13:41:02 -0800107 if (msaaSampleCount > 0) {
108 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
109 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaaSampleCount);
110 }
reed@android.com671cd652009-05-22 20:44:12 +0000111
joshualitta4d37972015-11-05 08:35:31 -0800112 info->fSampleCount = msaaSampleCount;
113 info->fStencilBits = 8;
114
joshualitt65d6fbb2015-11-04 13:41:02 -0800115 fGLContext = SDL_GL_CreateContext(fWindow);
116 if (!fGLContext) {
117 handle_error();
118 return false;
119 }
reed@android.com671cd652009-05-22 20:44:12 +0000120
joshualitt65d6fbb2015-11-04 13:41:02 -0800121 int success = SDL_GL_MakeCurrent(fWindow, fGLContext);
122 if (success != 0) {
123 handle_error();
124 return false;
125 }
reed@android.com671cd652009-05-22 20:44:12 +0000126
joshualitta4d37972015-11-05 08:35:31 -0800127 glViewport(0, 0, SkScalarFloorToInt(this->width()), SkScalarFloorToInt(this->height()));
joshualitt65d6fbb2015-11-04 13:41:02 -0800128 glClearColor(1, 1, 1, 1);
129 glClearStencil(0);
130 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
reed@android.comc3a8c5f2009-05-26 13:27:48 +0000131
joshualitt65d6fbb2015-11-04 13:41:02 -0800132 return true;
133}
134
135void SkOSWindow::present() {
136 SDL_GL_SwapWindow(fWindow);
137}
138
139bool SkOSWindow::makeFullscreen() {
140 SDL_SetWindowFullscreen(fWindow, SDL_WINDOW_FULLSCREEN);
141 return true;
142}
143
144void SkOSWindow::setVsync(bool vsync) {
145 SDL_GL_SetSwapInterval(vsync ? 1 : 0);
146}
147
148void SkOSWindow::closeWindow() {
149 fQuit = true;
150}
151
152static SkKey convert_sdlkey_to_skkey(SDL_Keycode src) {
153 switch (src) {
154 case SDLK_UP:
155 return kUp_SkKey;
156 case SDLK_DOWN:
157 return kDown_SkKey;
158 case SDLK_LEFT:
159 return kLeft_SkKey;
160 case SDLK_RIGHT:
161 return kRight_SkKey;
162 case SDLK_HOME:
163 return kHome_SkKey;
164 case SDLK_END:
165 return kEnd_SkKey;
166 case SDLK_ASTERISK:
167 return kStar_SkKey;
168 case SDLK_HASH:
169 return kHash_SkKey;
170 case SDLK_0:
171 return k0_SkKey;
172 case SDLK_1:
173 return k1_SkKey;
174 case SDLK_2:
175 return k2_SkKey;
176 case SDLK_3:
177 return k3_SkKey;
178 case SDLK_4:
179 return k4_SkKey;
180 case SDLK_5:
181 return k5_SkKey;
182 case SDLK_6:
183 return k6_SkKey;
184 case SDLK_7:
185 return k7_SkKey;
186 case SDLK_8:
187 return k8_SkKey;
188 case SDLK_9:
189 return k9_SkKey;
190 default:
191 return kNONE_SkKey;
reed@android.comc3a8c5f2009-05-26 13:27:48 +0000192 }
reed@android.com671cd652009-05-22 20:44:12 +0000193}
194
joshualitt65d6fbb2015-11-04 13:41:02 -0800195void SkOSWindow::handleEvents() {
196 SkEvent::ServiceQueueTimer();
197 SkEvent::ProcessEvent();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000198
joshualitt65d6fbb2015-11-04 13:41:02 -0800199 SDL_Event event;
200 while(SDL_PollEvent(&event)) {
201 switch (event.type) {
202 case SDL_MOUSEMOTION:
203 if (event.motion.state == SDL_PRESSED) {
204 this->handleClick(event.motion.x, event.motion.y,
205 SkView::Click::kMoved_State, nullptr);
reed@android.com671cd652009-05-22 20:44:12 +0000206 }
joshualitt65d6fbb2015-11-04 13:41:02 -0800207 break;
208 case SDL_MOUSEBUTTONDOWN:
209 case SDL_MOUSEBUTTONUP:
210 this->handleClick(event.button.x, event.button.y,
211 event.button.state == SDL_PRESSED ?
212 SkView::Click::kDown_State :
213 SkView::Click::kUp_State, nullptr);
214 break;
215 case SDL_KEYDOWN: {
216 SDL_Keycode key = event.key.keysym.sym;
217 SkKey sk = convert_sdlkey_to_skkey(key);
218 if (kNONE_SkKey != sk) {
219 if (event.key.state == SDL_PRESSED) {
220 this->handleKey(sk);
221 } else {
222 this->handleKeyUp(sk);
223 }
224 } else if (key == SDLK_ESCAPE) {
225 fQuit = true;
226 }
227 break;
reed@android.com671cd652009-05-22 20:44:12 +0000228 }
joshualitt65d6fbb2015-11-04 13:41:02 -0800229 case SDL_TEXTINPUT: {
230 size_t len = strlen(event.text.text);
231 for (size_t i = 0; i < len; i++) {
232 this->handleChar((SkUnichar)event.text.text[i]);
233 }
234 break;
235 }
236 case SDL_QUIT:
237 fQuit = true;
238 break;
239 default:
240 break;
reed@android.com671cd652009-05-22 20:44:12 +0000241 }
reed@android.com671cd652009-05-22 20:44:12 +0000242 }
243}
244
reed@android.com671cd652009-05-22 20:44:12 +0000245
246void SkOSWindow::onSetTitle(const char title[]) {
joshualitt65d6fbb2015-11-04 13:41:02 -0800247 SDL_SetWindowTitle(fWindow, title);
reed@android.com671cd652009-05-22 20:44:12 +0000248}
reed@android.com671cd652009-05-22 20:44:12 +0000249///////////////////////////////////////////////////////////////////////////////////////
250
251void SkEvent::SignalNonEmptyQueue() {
joshualitt65d6fbb2015-11-04 13:41:02 -0800252 // nothing to do, since we spin on our event-queue
reed@android.com671cd652009-05-22 20:44:12 +0000253}
254
joshualitt65d6fbb2015-11-04 13:41:02 -0800255void SkEvent::SignalQueueTimer(SkMSec delay) {
256 // just need to record the delay time. We handle waking up for it in
257}
258
joshualitta4d37972015-11-05 08:35:31 -0800259void SkOSWindow::onHandleInval(const SkIRect& rect) {
260}
joshualitt65d6fbb2015-11-04 13:41:02 -0800261
joshualitta4d37972015-11-05 08:35:31 -0800262void SkOSWindow::onPDFSaved(const char title[], const char desc[], const char path[]) {
263}
264
265//////////////////////////////////////////////////////////////////////////////////////////////
joshualitt65d6fbb2015-11-04 13:41:02 -0800266
267#include "SkApplication.h"
268#include "SkEvent.h"
269#include "SkWindow.h"
270
joshualitta4d37972015-11-05 08:35:31 -0800271#if defined(SK_BUILD_FOR_ANDROID)
272int SDL_main(int argc, char** argv) {
273#else
274int main(int argc, char** argv) {
275#endif
joshualitt65d6fbb2015-11-04 13:41:02 -0800276 SkOSWindow* window = create_sk_window(nullptr, argc, argv);
277
278 // drain any events that occurred before |window| was assigned.
279 while (SkEvent::ProcessEvent());
280
281 // Start normal Skia sequence
282 application_init();
283
284 window->loop();
285
286 delete window;
287 application_term();
reed@android.com671cd652009-05-22 20:44:12 +0000288 return 0;
289}