epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 1 | /* |
| 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.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 7 | #include "SkOSWindow_SDL.h" |
| 8 | #include "SkCanvas.h" |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 9 | |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 10 | #if defined(SK_BUILD_FOR_ANDROID) |
| 11 | #include <GLES/gl.h> |
| 12 | #else |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 13 | #include <GL/gl.h> |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 14 | #endif |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 15 | |
| 16 | const int SCREEN_WIDTH = 640; |
| 17 | const int SCREEN_HEIGHT = 480; |
| 18 | |
| 19 | static void handle_error() { |
| 20 | const char* error = SDL_GetError(); |
| 21 | SkDebugf("SDL Error: %s\n", error); |
| 22 | SDL_ClearError(); |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 23 | } |
| 24 | |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 25 | SkOSWindow::SkOSWindow(void* screen) : fQuit(false) , fGLContext(nullptr) { |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 26 | #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 | |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 65 | if (!fWindow) { |
| 66 | handle_error(); |
| 67 | return; |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 68 | } |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 69 | this->resize(SkIntToScalar(dm.w), SkIntToScalar(dm.h)); |
reed@android.com | c3a8c5f | 2009-05-26 13:27:48 +0000 | [diff] [blame] | 70 | } |
| 71 | |
| 72 | SkOSWindow::~SkOSWindow() { |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 73 | 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 | |
| 84 | void SkOSWindow::detach() { |
| 85 | if (fGLContext) { |
| 86 | SDL_GL_DeleteContext(fGLContext); |
| 87 | fGLContext = nullptr; |
reed@android.com | 25fc5b9 | 2009-05-29 03:40:05 +0000 | [diff] [blame] | 88 | } |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 89 | |
| 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.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 98 | } |
| 99 | |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 100 | bool 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.com | 25fc5b9 | 2009-05-29 03:40:05 +0000 | [diff] [blame] | 106 | |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 107 | if (msaaSampleCount > 0) { |
| 108 | SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); |
| 109 | SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaaSampleCount); |
| 110 | } |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 111 | |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 112 | info->fSampleCount = msaaSampleCount; |
| 113 | info->fStencilBits = 8; |
| 114 | |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 115 | fGLContext = SDL_GL_CreateContext(fWindow); |
| 116 | if (!fGLContext) { |
| 117 | handle_error(); |
| 118 | return false; |
| 119 | } |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 120 | |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 121 | int success = SDL_GL_MakeCurrent(fWindow, fGLContext); |
| 122 | if (success != 0) { |
| 123 | handle_error(); |
| 124 | return false; |
| 125 | } |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 126 | |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 127 | glViewport(0, 0, SkScalarFloorToInt(this->width()), SkScalarFloorToInt(this->height())); |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 128 | glClearColor(1, 1, 1, 1); |
| 129 | glClearStencil(0); |
| 130 | glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
reed@android.com | c3a8c5f | 2009-05-26 13:27:48 +0000 | [diff] [blame] | 131 | |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 132 | return true; |
| 133 | } |
| 134 | |
| 135 | void SkOSWindow::present() { |
| 136 | SDL_GL_SwapWindow(fWindow); |
| 137 | } |
| 138 | |
| 139 | bool SkOSWindow::makeFullscreen() { |
| 140 | SDL_SetWindowFullscreen(fWindow, SDL_WINDOW_FULLSCREEN); |
| 141 | return true; |
| 142 | } |
| 143 | |
| 144 | void SkOSWindow::setVsync(bool vsync) { |
| 145 | SDL_GL_SetSwapInterval(vsync ? 1 : 0); |
| 146 | } |
| 147 | |
| 148 | void SkOSWindow::closeWindow() { |
| 149 | fQuit = true; |
| 150 | } |
| 151 | |
| 152 | static 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.com | c3a8c5f | 2009-05-26 13:27:48 +0000 | [diff] [blame] | 192 | } |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 193 | } |
| 194 | |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 195 | void SkOSWindow::handleEvents() { |
| 196 | SkEvent::ServiceQueueTimer(); |
| 197 | SkEvent::ProcessEvent(); |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 198 | |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 199 | 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.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 206 | } |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 207 | 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.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 228 | } |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 229 | 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.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 241 | } |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 242 | } |
| 243 | } |
| 244 | |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 245 | |
| 246 | void SkOSWindow::onSetTitle(const char title[]) { |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 247 | SDL_SetWindowTitle(fWindow, title); |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 248 | } |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 249 | /////////////////////////////////////////////////////////////////////////////////////// |
| 250 | |
| 251 | void SkEvent::SignalNonEmptyQueue() { |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 252 | // nothing to do, since we spin on our event-queue |
reed@android.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 253 | } |
| 254 | |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 255 | void SkEvent::SignalQueueTimer(SkMSec delay) { |
| 256 | // just need to record the delay time. We handle waking up for it in |
| 257 | } |
| 258 | |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 259 | void SkOSWindow::onHandleInval(const SkIRect& rect) { |
| 260 | } |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 261 | |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 262 | void SkOSWindow::onPDFSaved(const char title[], const char desc[], const char path[]) { |
| 263 | } |
| 264 | |
| 265 | ////////////////////////////////////////////////////////////////////////////////////////////// |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 266 | |
| 267 | #include "SkApplication.h" |
| 268 | #include "SkEvent.h" |
| 269 | #include "SkWindow.h" |
| 270 | |
joshualitt | a4d3797 | 2015-11-05 08:35:31 -0800 | [diff] [blame^] | 271 | #if defined(SK_BUILD_FOR_ANDROID) |
| 272 | int SDL_main(int argc, char** argv) { |
| 273 | #else |
| 274 | int main(int argc, char** argv) { |
| 275 | #endif |
joshualitt | 65d6fbb | 2015-11-04 13:41:02 -0800 | [diff] [blame] | 276 | 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.com | 671cd65 | 2009-05-22 20:44:12 +0000 | [diff] [blame] | 288 | return 0; |
| 289 | } |