Atlas - SDL_qnxvideo.c
Home / ext / SDL / src / video / qnx Lines: 1 | Size: 10049 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 2017 BlackBerry Limited 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "../../SDL_internal.h" 22#include "../SDL_sysvideo.h" 23#include "../../events/SDL_keyboard_c.h" 24#include "../../events/SDL_mouse_c.h" 25#include "SDL_qnx.h" 26 27static screen_context_t context; 28static screen_event_t event; 29 30/** 31 * Initializes the QNX video plugin. 32 * Creates the Screen context and event handles used for all window operations 33 * by the plugin. 34 * @param SDL_VideoDevice *_this 35 * @return 0 if successful, -1 on error 36 */ 37static bool videoInit(SDL_VideoDevice *_this) 38{ 39 SDL_VideoDisplay display; 40 41 if (screen_create_context(&context, 0) < 0) { 42 return false; 43 } 44 45 if (screen_create_event(&event) < 0) { 46 return false; 47 } 48 49 SDL_zero(display); 50 51 if (SDL_AddVideoDisplay(&display, false) == 0) { 52 return false; 53 } 54 55 // Assume we have a mouse and keyboard 56 SDL_AddKeyboard(SDL_DEFAULT_KEYBOARD_ID, NULL); 57 SDL_AddMouse(SDL_DEFAULT_MOUSE_ID, NULL); 58 59 return true; 60} 61 62static void videoQuit(SDL_VideoDevice *_this) 63{ 64} 65 66/** 67 * Creates a new native Screen window and associates it with the given SDL 68 * window. 69 * @param SDL_VideoDevice *_this 70 * @param window SDL window to initialize 71 * @return 0 if successful, -1 on error 72 */ 73static bool createWindow(SDL_VideoDevice *_this, SDL_Window *window) 74{ 75 window_impl_t *impl; 76 int size[2]; 77 int numbufs; 78 int format; 79 int usage; 80 81 impl = SDL_calloc(1, sizeof(*impl)); 82 if (!impl) { 83 return false; 84 } 85 86 // Create a native window. 87 if (screen_create_window(&impl->window, context) < 0) { 88 goto fail; 89 } 90 91 // Set the native window's size to match the SDL window. 92 size[0] = window->w; 93 size[1] = window->h; 94 95 if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SIZE, 96 size) < 0) { 97 goto fail; 98 } 99 100 if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SOURCE_SIZE, 101 size) < 0) { 102 goto fail; 103 } 104 105 // Create window buffer(s). 106 if (window->flags & SDL_WINDOW_OPENGL) { 107 if (glGetConfig(&impl->conf, &format) < 0) { 108 goto fail; 109 } 110 numbufs = 2; 111 112 usage = SCREEN_USAGE_OPENGL_ES2; 113 if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_USAGE, 114 &usage) < 0) { 115 return false; 116 } 117 } else { 118 format = SCREEN_FORMAT_RGBX8888; 119 numbufs = 1; 120 } 121 122 // Set pixel format. 123 if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_FORMAT, 124 &format) < 0) { 125 goto fail; 126 } 127 128 // Create buffer(s). 129 if (screen_create_window_buffers(impl->window, numbufs) < 0) { 130 goto fail; 131 } 132 133 window->internal = impl; 134 return true; 135 136fail: 137 if (impl->window) { 138 screen_destroy_window(impl->window); 139 } 140 141 SDL_free(impl); 142 return false; 143} 144 145/** 146 * Gets a pointer to the Screen buffer associated with the given window. Note 147 * that the buffer is actually created in createWindow(). 148 * @param SDL_VideoDevice *_this 149 * @param window SDL window to get the buffer for 150 * @param[out] pixles Holds a pointer to the window's buffer 151 * @param[out] format Holds the pixel format for the buffer 152 * @param[out] pitch Holds the number of bytes per line 153 * @return 0 if successful, -1 on error 154 */ 155static bool createWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window * window, SDL_PixelFormat * format, 156 void ** pixels, int *pitch) 157{ 158 window_impl_t *impl = (window_impl_t *)window->internal; 159 screen_buffer_t buffer; 160 161 // Get a pointer to the buffer's memory. 162 if (screen_get_window_property_pv(impl->window, SCREEN_PROPERTY_BUFFERS, 163 (void **)&buffer) < 0) { 164 return false; 165 } 166 167 if (screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, 168 pixels) < 0) { 169 return false; 170 } 171 172 // Set format and pitch. 173 if (screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, 174 pitch) < 0) { 175 return false; 176 } 177 178 *format = SDL_PIXELFORMAT_XRGB8888; 179 return true; 180} 181 182/** 183 * Informs the window manager that the window needs to be updated. 184 * @param SDL_VideoDevice *_this 185 * @param window The window to update 186 * @param rects An array of reectangular areas to update 187 * @param numrects Rect array length 188 * @return 0 if successful, -1 on error 189 */ 190static bool updateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, 191 int numrects) 192{ 193 window_impl_t *impl = (window_impl_t *)window->internal; 194 screen_buffer_t buffer; 195 196 if (screen_get_window_property_pv(impl->window, SCREEN_PROPERTY_BUFFERS, 197 (void **)&buffer) < 0) { 198 return false; 199 } 200 201 screen_post_window(impl->window, buffer, numrects, (int *)rects, 0); 202 screen_flush_context(context, 0); 203 return true; 204} 205 206/** 207 * Runs the main event loop. 208 * @param SDL_VideoDevice *_this 209 */ 210static void pumpEvents(SDL_VideoDevice *_this) 211{ 212 int type; 213 214 for (;;) { 215 if (screen_get_event(context, event, 0) < 0) { 216 break; 217 } 218 219 if (screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type) 220 < 0) { 221 break; 222 } 223 224 if (type == SCREEN_EVENT_NONE) { 225 break; 226 } 227 228 switch (type) { 229 case SCREEN_EVENT_KEYBOARD: 230 handleKeyboardEvent(event); 231 break; 232 233 default: 234 break; 235 } 236 } 237} 238 239/** 240 * Updates the size of the native window using the geometry of the SDL window. 241 * @param SDL_VideoDevice *_this 242 * @param window SDL window to update 243 */ 244static void setWindowSize(SDL_VideoDevice *_this, SDL_Window *window) 245{ 246 window_impl_t *impl = (window_impl_t *)window->internal; 247 int size[2]; 248 249 size[0] = window->pending.w; 250 size[1] = window->pending.h; 251 252 screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SIZE, size); 253 screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SOURCE_SIZE, size); 254} 255 256/** 257 * Makes the native window associated with the given SDL window visible. 258 * @param SDL_VideoDevice *_this 259 * @param window SDL window to update 260 */ 261static void showWindow(SDL_VideoDevice *_this, SDL_Window *window) 262{ 263 window_impl_t *impl = (window_impl_t *)window->internal; 264 const int visible = 1; 265 266 screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_VISIBLE, 267 &visible); 268} 269 270/** 271 * Makes the native window associated with the given SDL window invisible. 272 * @param SDL_VideoDevice *_this 273 * @param window SDL window to update 274 */ 275static void hideWindow(SDL_VideoDevice *_this, SDL_Window *window) 276{ 277 window_impl_t *impl = (window_impl_t *)window->internal; 278 const int visible = 0; 279 280 screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_VISIBLE, 281 &visible); 282} 283 284/** 285 * Destroys the native window associated with the given SDL window. 286 * @param SDL_VideoDevice *_this 287 * @param window SDL window that is being destroyed 288 */ 289static void destroyWindow(SDL_VideoDevice *_this, SDL_Window *window) 290{ 291 window_impl_t *impl = (window_impl_t *)window->internal; 292 293 if (impl) { 294 screen_destroy_window(impl->window); 295 window->internal = NULL; 296 } 297} 298 299/** 300 * Frees the plugin object created by createDevice(). 301 * @param device Plugin object to free 302 */ 303static void deleteDevice(SDL_VideoDevice *device) 304{ 305 SDL_free(device); 306} 307 308/** 309 * Creates the QNX video plugin used by SDL. 310 * @return Initialized device if successful, NULL otherwise 311 */ 312static SDL_VideoDevice *createDevice(void) 313{ 314 SDL_VideoDevice *device; 315 316 device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); 317 if (!device) { 318 return NULL; 319 } 320 321 device->internal = NULL; 322 device->VideoInit = videoInit; 323 device->VideoQuit = videoQuit; 324 device->CreateSDLWindow = createWindow; 325 device->CreateWindowFramebuffer = createWindowFramebuffer; 326 device->UpdateWindowFramebuffer = updateWindowFramebuffer; 327 device->SetWindowSize = setWindowSize; 328 device->ShowWindow = showWindow; 329 device->HideWindow = hideWindow; 330 device->PumpEvents = pumpEvents; 331 device->DestroyWindow = destroyWindow; 332 333 device->GL_LoadLibrary = glLoadLibrary; 334 device->GL_GetProcAddress = glGetProcAddress; 335 device->GL_CreateContext = glCreateContext; 336 device->GL_SetSwapInterval = glSetSwapInterval; 337 device->GL_SwapWindow = glSwapWindow; 338 device->GL_MakeCurrent = glMakeCurrent; 339 device->GL_DestroyContext = glDeleteContext; 340 device->GL_UnloadLibrary = glUnloadLibrary; 341 342 device->free = deleteDevice; 343 return device; 344} 345 346VideoBootStrap QNX_bootstrap = { 347 "qnx", "QNX Screen", 348 createDevice, 349 NULL, // no ShowMessageBox implementation 350 false 351}; 352[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.