slouken@0: /* slouken@0: SDL - Simple DirectMedia Layer slouken@1312: Copyright (C) 1997-2006 Sam Lantinga slouken@0: slouken@0: This library is free software; you can redistribute it and/or slouken@1312: modify it under the terms of the GNU Lesser General Public slouken@0: License as published by the Free Software Foundation; either slouken@1312: version 2.1 of the License, or (at your option) any later version. slouken@0: slouken@0: This library is distributed in the hope that it will be useful, slouken@0: but WITHOUT ANY WARRANTY; without even the implied warranty of slouken@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU slouken@1312: Lesser General Public License for more details. slouken@0: slouken@1312: You should have received a copy of the GNU Lesser General Public slouken@1312: License along with this library; if not, write to the Free Software slouken@1312: Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA slouken@0: slouken@0: Sam Lantinga slouken@252: slouken@libsdl.org slouken@0: */ slouken@1402: #include "SDL_config.h" slouken@0: slouken@0: /* The high-level video driver subsystem */ slouken@0: slouken@0: #include "SDL.h" slouken@0: #include "SDL_sysvideo.h" slouken@0: #include "SDL_blit.h" slouken@0: #include "SDL_pixels_c.h" slouken@1895: #include "SDL_renderer_sw.h" slouken@1361: #include "../events/SDL_sysevents.h" slouken@1361: #include "../events/SDL_events_c.h" slouken@0: slouken@0: /* Available video drivers */ slouken@0: static VideoBootStrap *bootstrap[] = { slouken@1361: #if SDL_VIDEO_DRIVER_QUARTZ slouken@1895: &QZ_bootstrap, icculus@1133: #endif slouken@1361: #if SDL_VIDEO_DRIVER_X11 slouken@1895: &X11_bootstrap, slouken@0: #endif slouken@1361: #if SDL_VIDEO_DRIVER_DGA slouken@1895: &DGA_bootstrap, slouken@0: #endif slouken@1361: #if SDL_VIDEO_DRIVER_NANOX slouken@1895: &NX_bootstrap, slouken@30: #endif slouken@1361: #if SDL_VIDEO_DRIVER_IPOD slouken@1895: &iPod_bootstrap, icculus@1140: #endif slouken@1361: #if SDL_VIDEO_DRIVER_QTOPIA slouken@1895: &Qtopia_bootstrap, slouken@567: #endif slouken@1361: #if SDL_VIDEO_DRIVER_WSCONS slouken@1895: &WSCONS_bootstrap, icculus@1187: #endif slouken@1361: #if SDL_VIDEO_DRIVER_FBCON slouken@1895: &FBCON_bootstrap, slouken@0: #endif slouken@1361: #if SDL_VIDEO_DRIVER_DIRECTFB slouken@1895: &DirectFB_bootstrap, slouken@167: #endif slouken@1361: #if SDL_VIDEO_DRIVER_PS2GS slouken@1895: &PS2GS_bootstrap, slouken@0: #endif slouken@1361: #if SDL_VIDEO_DRIVER_GGI slouken@1895: &GGI_bootstrap, slouken@0: #endif slouken@1361: #if SDL_VIDEO_DRIVER_VGL slouken@1895: &VGL_bootstrap, slouken@75: #endif slouken@1361: #if SDL_VIDEO_DRIVER_SVGALIB slouken@1895: &SVGALIB_bootstrap, slouken@0: #endif slouken@1361: #if SDL_VIDEO_DRIVER_GAPI slouken@1895: &GAPI_bootstrap, slouken@1361: #endif slouken@1895: #if SDL_VIDEO_DRIVER_WIN32 slouken@1895: &WIN32_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_BWINDOW slouken@1895: &BWINDOW_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_TOOLBOX slouken@1895: &TOOLBOX_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_DRAWSPROCKET slouken@1895: &DSp_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_CYBERGRAPHICS slouken@1895: &CGX_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_PHOTON slouken@1895: &ph_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_EPOC slouken@1895: &EPOC_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_XBIOS slouken@1895: &XBIOS_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_GEM slouken@1895: &GEM_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_PICOGUI slouken@1895: &PG_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_DC slouken@1895: &DC_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_RISCOS slouken@1895: &RISCOS_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_OS2FS slouken@1895: &OS2FSLib_bootstrap, slouken@1361: #endif slouken@1361: #if SDL_VIDEO_DRIVER_AALIB slouken@1895: &AALIB_bootstrap, slouken@0: #endif slouken@1361: #if SDL_VIDEO_DRIVER_DUMMY slouken@1895: &DUMMY_bootstrap, slouken@610: #endif slouken@1895: #if SDL_VIDEO_DRIVER_GLSDL slouken@1895: &glSDL_bootstrap, slouken@1895: #endif slouken@1895: NULL slouken@0: }; slouken@173: slouken@1895: static SDL_VideoDevice *_this = NULL; slouken@0: slouken@0: /* Various local functions */ slouken@0: int SDL_VideoInit(const char *driver_name, Uint32 flags); slouken@0: void SDL_VideoQuit(void); slouken@0: slouken@1895: static int slouken@1895: cmpmodes(const void *A, const void *B) slouken@1895: { slouken@1895: SDL_DisplayMode a = *(const SDL_DisplayMode *) A; slouken@1895: SDL_DisplayMode b = *(const SDL_DisplayMode *) B; slouken@0: slouken@1895: if (a.w != b.w) { slouken@1895: return b.w - a.w; slouken@1895: } slouken@1895: if (a.h != b.h) { slouken@1895: return b.h - a.h; slouken@1895: } slouken@1895: if (SDL_BITSPERPIXEL(a.format) != SDL_BITSPERPIXEL(b.format)) { slouken@1895: return SDL_BITSPERPIXEL(b.format) - SDL_BITSPERPIXEL(a.format); slouken@1895: } slouken@1895: if (a.refresh_rate != b.refresh_rate) { slouken@1895: return b.refresh_rate - a.refresh_rate; slouken@1895: } slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_GetNumVideoDrivers(void) slouken@1895: { slouken@1895: return SDL_arraysize(bootstrap) - 1; slouken@1895: } slouken@1895: slouken@1895: const char * slouken@1895: SDL_GetVideoDriver(int index) slouken@1895: { slouken@1895: if (index >= 0 && index < SDL_GetNumVideoDrivers()) { slouken@1895: return bootstrap[index]->name; slouken@1895: } slouken@1895: return NULL; slouken@1895: } slouken@0: slouken@0: /* slouken@0: * Initialize the video and event subsystems -- determine native pixel format slouken@0: */ slouken@1895: int slouken@1895: SDL_VideoInit(const char *driver_name, Uint32 flags) slouken@0: { slouken@1895: SDL_VideoDevice *video; slouken@1895: int index; slouken@1895: int i; slouken@0: slouken@1895: /* Toggle the event thread flags, based on OS requirements */ slouken@0: #if defined(MUST_THREAD_EVENTS) slouken@1895: flags |= SDL_INIT_EVENTTHREAD; slouken@0: #elif defined(CANT_THREAD_EVENTS) slouken@1895: if ((flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD) { slouken@1895: SDL_SetError("OS doesn't support threaded events"); slouken@1895: return -1; slouken@1895: } slouken@0: #endif slouken@0: slouken@1895: /* Start the event loop */ slouken@1895: if (SDL_StartEventLoop(flags) < 0) { slouken@1895: return -1; slouken@1895: } slouken@0: slouken@1895: /* Check to make sure we don't overwrite '_this' */ slouken@1895: if (_this != NULL) { slouken@1895: SDL_VideoQuit(); slouken@1895: } slouken@0: slouken@1895: /* Select the proper video driver */ slouken@1895: index = 0; slouken@1895: video = NULL; slouken@1895: if (driver_name != NULL) { slouken@1895: for (i = 0; bootstrap[i]; ++i) { slouken@1895: if (SDL_strncmp(bootstrap[i]->name, driver_name, slouken@1895: SDL_strlen(bootstrap[i]->name)) == 0) { slouken@1895: if (bootstrap[i]->available()) { slouken@1895: video = bootstrap[i]->create(index); slouken@1895: } slouken@1895: break; slouken@1895: } slouken@1895: } slouken@1895: } else { slouken@1895: for (i = 0; bootstrap[i]; ++i) { slouken@1895: if (bootstrap[i]->available()) { slouken@1895: video = bootstrap[i]->create(index); slouken@1895: if (video != NULL) { slouken@1895: break; slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: if (video == NULL) { slouken@1895: if (driver_name) { slouken@1895: SDL_SetError("%s not available", driver_name); slouken@1895: } else { slouken@1895: SDL_SetError("No available video device"); slouken@1895: } slouken@1895: return -1; slouken@1895: } slouken@1895: _this = video; slouken@1895: _this->name = bootstrap[i]->name; slouken@1895: _this->next_object_id = 1; slouken@0: slouken@0: slouken@1895: /* Set some very sane GL defaults */ slouken@1895: _this->gl_config.driver_loaded = 0; slouken@1895: _this->gl_config.dll_handle = NULL; slouken@1895: _this->gl_config.red_size = 3; slouken@1895: _this->gl_config.green_size = 3; slouken@1895: _this->gl_config.blue_size = 2; slouken@1895: _this->gl_config.alpha_size = 0; slouken@1895: _this->gl_config.buffer_size = 0; slouken@1895: _this->gl_config.depth_size = 16; slouken@1895: _this->gl_config.stencil_size = 0; slouken@1895: _this->gl_config.double_buffer = 1; slouken@1895: _this->gl_config.accum_red_size = 0; slouken@1895: _this->gl_config.accum_green_size = 0; slouken@1895: _this->gl_config.accum_blue_size = 0; slouken@1895: _this->gl_config.accum_alpha_size = 0; slouken@1895: _this->gl_config.stereo = 0; slouken@1895: _this->gl_config.multisamplebuffers = 0; slouken@1895: _this->gl_config.multisamplesamples = 0; slouken@1895: _this->gl_config.accelerated = -1; /* not known, don't set */ slouken@0: slouken@1895: /* Initialize the video subsystem */ slouken@1895: if (_this->VideoInit(_this) < 0) { slouken@1895: SDL_VideoQuit(); slouken@1895: return -1; slouken@1895: } slouken@0: slouken@1895: /* Make sure some displays were added */ slouken@1895: if (_this->num_displays == 0) { slouken@1895: SDL_SetError("The video driver did not add any displays"); slouken@1895: SDL_VideoQuit(); slouken@1895: return (-1); slouken@1895: } slouken@0: slouken@1895: /* The software renderer is always available */ slouken@1895: for (i = 0; i < _this->num_displays; ++i) { slouken@1895: if (_this->displays[i].num_render_drivers > 0) { slouken@1895: SDL_AddRenderDriver(i, &SDL_SW_RenderDriver); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: /* We're ready to go! */ slouken@1895: return 0; slouken@0: } slouken@0: slouken@1895: const char * slouken@1895: SDL_GetCurrentVideoDriver() slouken@0: { slouken@1895: if (!_this) { slouken@1895: return NULL; slouken@1895: } slouken@1895: return _this->name; slouken@0: } slouken@0: slouken@1895: SDL_VideoDevice * slouken@1895: SDL_GetVideoDevice() slouken@0: { slouken@1895: return _this; slouken@0: } slouken@0: slouken@1895: int slouken@1895: SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode) slouken@0: { slouken@1895: SDL_VideoDisplay display; slouken@0: slouken@1895: SDL_zero(display); slouken@1895: if (desktop_mode) { slouken@1895: display.desktop_mode = *desktop_mode; slouken@1895: } slouken@1895: display.current_mode = display.desktop_mode; slouken@1895: slouken@1895: return SDL_AddVideoDisplay(&display); slouken@0: } slouken@0: slouken@1895: int slouken@1895: SDL_AddVideoDisplay(const SDL_VideoDisplay * display) slouken@0: { slouken@1895: SDL_VideoDisplay *displays; slouken@1895: int index = -1; slouken@0: slouken@1895: displays = slouken@1895: SDL_realloc(_this->displays, slouken@1895: (_this->num_displays + 1) * sizeof(*displays)); slouken@1895: if (displays) { slouken@1895: index = _this->num_displays++; slouken@1895: displays[index] = *display; slouken@1895: displays[index].device = _this; slouken@1895: _this->displays = displays; slouken@1895: } else { slouken@1895: SDL_OutOfMemory(); slouken@1895: } slouken@1895: return index; slouken@0: } slouken@0: slouken@1895: int slouken@1895: SDL_GetNumVideoDisplays(void) slouken@0: { slouken@1895: if (!_this) { slouken@1895: return 0; slouken@1895: } slouken@1895: return _this->num_displays; slouken@0: } slouken@0: slouken@1895: int slouken@1895: SDL_SelectVideoDisplay(int index) slouken@0: { slouken@1895: if (!_this) { slouken@1895: SDL_SetError("Video subsystem has not been initialized"); slouken@1895: return (-1); slouken@1895: } slouken@1895: if (index >= 0) { slouken@1895: if (index >= _this->num_displays) { slouken@1895: SDL_SetError("index must be in the range 0 - %d", slouken@1895: _this->num_displays - 1); slouken@1895: return -1; slouken@1895: } slouken@1895: _this->current_display = index; slouken@1895: } slouken@1895: return _this->current_display; slouken@0: } slouken@0: slouken@1895: SDL_bool slouken@1895: SDL_AddDisplayMode(int displayIndex, const SDL_DisplayMode * mode) slouken@0: { slouken@1895: SDL_VideoDisplay *display = &_this->displays[displayIndex]; slouken@1895: SDL_DisplayMode *modes; slouken@1895: int i, nmodes; slouken@0: slouken@1895: /* Make sure we don't already have the mode in the list */ slouken@1895: modes = display->display_modes; slouken@1895: nmodes = display->num_display_modes; slouken@1895: for (i = nmodes; i--;) { slouken@1895: if (SDL_memcmp(mode, &modes[i], sizeof(*mode)) == 0) { slouken@1895: return SDL_FALSE; slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: /* Go ahead and add the new mode */ slouken@1895: if (nmodes == display->max_display_modes) { slouken@1895: modes = slouken@1895: SDL_realloc(modes, slouken@1895: (display->max_display_modes + 32) * sizeof(*modes)); slouken@1895: if (!modes) { slouken@1895: return SDL_FALSE; slouken@1895: } slouken@1895: display->display_modes = modes; slouken@1895: display->max_display_modes += 32; slouken@1895: } slouken@1895: modes[nmodes] = *mode; slouken@1895: display->num_display_modes++; slouken@1895: slouken@1895: return SDL_TRUE; slouken@0: } slouken@0: slouken@1895: int slouken@1895: SDL_GetNumDisplayModes() slouken@0: { slouken@1895: if (_this) { slouken@1895: SDL_VideoDisplay *display = &SDL_CurrentDisplay; slouken@1895: if (!display->num_display_modes && _this->GetDisplayModes) { slouken@1895: _this->GetDisplayModes(_this); slouken@1895: SDL_qsort(display->display_modes, display->num_display_modes, slouken@1895: sizeof(SDL_DisplayMode), cmpmodes); slouken@1895: } slouken@1895: return display->num_display_modes; slouken@1895: } slouken@1895: return 0; slouken@0: } slouken@0: slouken@1895: const SDL_DisplayMode * slouken@1895: SDL_GetDisplayMode(int index) slouken@0: { slouken@1895: if (index < 0 || index >= SDL_GetNumDisplayModes()) { slouken@1895: SDL_SetError("index must be in the range of 0 - %d", slouken@1895: SDL_GetNumDisplayModes() - 1); slouken@1895: return NULL; slouken@1895: } slouken@1895: return &SDL_CurrentDisplay.display_modes[index]; slouken@0: } slouken@0: slouken@1895: const SDL_DisplayMode * slouken@1895: SDL_GetDesktopDisplayMode(void) slouken@0: { slouken@1895: if (_this) { slouken@1895: return &SDL_CurrentDisplay.desktop_mode; slouken@1895: } slouken@1895: return NULL; slouken@0: } slouken@0: slouken@1895: const SDL_DisplayMode * slouken@1895: SDL_GetCurrentDisplayMode(void) slouken@0: { slouken@1895: if (_this) { slouken@1895: return &SDL_CurrentDisplay.current_mode; slouken@1895: } slouken@1895: return NULL; slouken@0: } slouken@0: slouken@1895: SDL_DisplayMode * slouken@1895: SDL_GetClosestDisplayMode(const SDL_DisplayMode * mode, slouken@1895: SDL_DisplayMode * closest) slouken@0: { slouken@1895: Uint32 target_format; slouken@1895: int target_refresh_rate; slouken@1895: int i; slouken@1895: SDL_DisplayMode *current, *match; slouken@0: slouken@1895: if (!_this || !mode || !closest) { slouken@1895: return NULL; slouken@1895: } slouken@0: slouken@1895: /* Default to the desktop format */ slouken@1895: if (mode->format) { slouken@1895: target_format = mode->format; slouken@1895: } else { slouken@1895: target_format = SDL_CurrentDisplay.desktop_mode.format; slouken@1895: } slouken@0: slouken@1895: /* Default to the desktop refresh rate */ slouken@1895: if (mode->refresh_rate) { slouken@1895: target_refresh_rate = mode->refresh_rate; slouken@1895: } else { slouken@1895: target_refresh_rate = SDL_CurrentDisplay.desktop_mode.refresh_rate; slouken@1895: } slouken@0: slouken@1895: match = NULL; slouken@1895: for (i = 0; i < SDL_GetNumDisplayModes(); ++i) { slouken@1895: current = &SDL_CurrentDisplay.display_modes[i]; slouken@1895: slouken@1895: if ((current->w && current->h) && slouken@1895: (current->w < mode->w || current->h < mode->h)) { slouken@1895: /* Out of sorted modes large enough here */ slouken@1895: break; slouken@1895: } slouken@1895: if (!match || current->w < match->w || current->h < match->h) { slouken@1895: match = current; slouken@1895: continue; slouken@1895: } slouken@1895: if (current->format != match->format) { slouken@1895: /* Sorted highest depth to lowest */ slouken@1895: if (current->format == target_format || slouken@1895: (SDL_BITSPERPIXEL(current->format) >= slouken@1895: SDL_BITSPERPIXEL(target_format) slouken@1895: && SDL_PIXELTYPE(current->format) == slouken@1895: SDL_PIXELTYPE(target_format))) { slouken@1895: match = current; slouken@1895: } slouken@1895: continue; slouken@1895: } slouken@1895: if (current->refresh_rate != match->refresh_rate) { slouken@1895: /* Sorted highest refresh to lowest */ slouken@1895: if (current->refresh_rate >= target_refresh_rate) { slouken@1895: match = current; slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: if (match) { slouken@1895: if (match->format) { slouken@1895: closest->format = match->format; slouken@1895: } else { slouken@1895: closest->format = mode->format; slouken@1895: } slouken@1895: if (match->w && match->h) { slouken@1895: closest->w = match->w; slouken@1895: closest->h = match->h; slouken@1895: } else { slouken@1895: closest->w = mode->w; slouken@1895: closest->h = mode->h; slouken@1895: } slouken@1895: if (match->refresh_rate) { slouken@1895: closest->refresh_rate = match->refresh_rate; slouken@1895: } else { slouken@1895: closest->refresh_rate = mode->refresh_rate; slouken@1895: } slouken@1895: closest->driverdata = match->driverdata; slouken@1895: slouken@1895: /* Pick some reasonable defaults if the app and driver don't care */ slouken@1895: if (!closest->format) { slouken@1895: closest->format = SDL_PixelFormat_RGB888; slouken@1895: } slouken@1895: if (!closest->w) { slouken@1895: closest->w = 640; slouken@1895: } slouken@1895: if (!closest->h) { slouken@1895: closest->h = 480; slouken@1895: } slouken@1895: return closest; slouken@1895: } slouken@1895: return NULL; slouken@0: } slouken@0: slouken@1895: int slouken@1895: SDL_SetDisplayMode(const SDL_DisplayMode * mode) slouken@0: { slouken@1895: SDL_VideoDisplay *display; slouken@1895: SDL_DisplayMode display_mode; slouken@1895: int i, ncolors; slouken@0: slouken@1895: if (!_this) { slouken@1895: SDL_SetError("Video subsystem has not been initialized"); slouken@1895: return -1; slouken@1895: } slouken@0: slouken@1895: if (!mode) { slouken@1895: mode = SDL_GetDesktopDisplayMode(); slouken@1895: } slouken@1895: display = &SDL_CurrentDisplay; slouken@1895: display_mode = *mode; slouken@1895: slouken@1895: /* Default to the current mode */ slouken@1895: if (!display_mode.format) { slouken@1895: display_mode.format = display->current_mode.format; slouken@1895: } slouken@1895: if (!display_mode.w) { slouken@1895: display_mode.w = display->current_mode.w; slouken@1895: } slouken@1895: if (!display_mode.h) { slouken@1895: display_mode.h = display->current_mode.h; slouken@1895: } slouken@1895: if (!display_mode.refresh_rate) { slouken@1895: display_mode.refresh_rate = display->current_mode.refresh_rate; slouken@1895: } slouken@1895: slouken@1895: /* Get a good video mode, the closest one possible */ slouken@1895: if (!SDL_GetClosestDisplayMode(&display_mode, &display_mode)) { slouken@1895: SDL_SetError("No video mode large enough for %dx%d", slouken@1895: display_mode.w, display_mode.h); slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: /* See if there's anything left to do */ slouken@1895: if (SDL_memcmp slouken@1895: (&display_mode, SDL_GetCurrentDisplayMode(), slouken@1895: sizeof(display_mode)) == 0) { slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: /* Actually change the display mode */ slouken@1895: if (_this->SetDisplayMode(_this, &display_mode) < 0) { slouken@1895: return -1; slouken@1895: } slouken@1895: display->current_mode = display_mode; slouken@1895: slouken@1895: /* Set up a palette, if necessary */ slouken@1895: if (SDL_ISPIXELFORMAT_INDEXED(display_mode.format)) { slouken@1895: ncolors = (1 << SDL_BITSPERPIXEL(display_mode.format)); slouken@1895: } else { slouken@1895: ncolors = 0; slouken@1895: } slouken@1895: if ((!ncolors && display->palette) || (ncolors && !display->palette) slouken@1895: || (ncolors && ncolors != display->palette->ncolors)) { slouken@1895: if (display->palette) { slouken@1895: SDL_FreePalette(display->palette); slouken@1895: display->palette = NULL; slouken@1895: } slouken@1895: if (ncolors) { slouken@1895: display->palette = SDL_AllocPalette(ncolors); slouken@1895: if (!display->palette) { slouken@1895: return -1; slouken@1895: } slouken@1895: SDL_DitherColors(display->palette->colors, slouken@1895: SDL_BITSPERPIXEL(display_mode.format)); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: /* Move any fullscreen windows into position */ slouken@1895: for (i = 0; i < display->num_windows; ++i) { slouken@1895: SDL_Window *window = &display->windows[i]; slouken@1895: if (FULLSCREEN_VISIBLE(window)) { slouken@1895: SDL_SetWindowPosition(window->id, slouken@1895: ((display_mode.w - window->w) / 2), slouken@1895: ((display_mode.h - window->h) / 2)); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: return 0; slouken@0: } slouken@0: slouken@1895: int slouken@1895: SDL_SetFullscreenDisplayMode(const SDL_DisplayMode * mode) slouken@0: { slouken@1895: SDL_VideoDisplay *display; slouken@1895: int i; slouken@0: slouken@1895: if (!_this) { slouken@1895: SDL_SetError("Video subsystem has not been initialized"); slouken@1895: return -1; slouken@1895: } slouken@0: slouken@1895: display = &SDL_CurrentDisplay; slouken@1895: if (mode) { slouken@1895: SDL_GetClosestDisplayMode(mode, &display->desired_mode); slouken@1895: display->fullscreen_mode = &display->desired_mode; slouken@1895: } else { slouken@1895: display->fullscreen_mode = NULL; slouken@1895: } slouken@1895: slouken@1895: /* Actually set the mode if we have a fullscreen window visible */ slouken@1895: for (i = 0; i < display->num_windows; ++i) { slouken@1895: SDL_Window *window = &display->windows[i]; slouken@1895: if (FULLSCREEN_VISIBLE(window)) { slouken@1895: return SDL_SetDisplayMode(display->fullscreen_mode); slouken@1895: } slouken@1895: } slouken@1895: return 0; slouken@0: } slouken@0: slouken@1895: const SDL_DisplayMode * slouken@1895: SDL_GetFullscreenDisplayMode(void) slouken@0: { slouken@1895: if (_this) { slouken@1895: return SDL_CurrentDisplay.fullscreen_mode; slouken@1895: } slouken@1895: return NULL; slouken@0: } slouken@0: slouken@1895: int slouken@1895: SDL_SetDisplayPalette(const SDL_Color * colors, int firstcolor, int ncolors) slouken@0: { slouken@1895: SDL_Palette *palette; slouken@1895: int status = 0; slouken@0: slouken@1895: if (!_this) { slouken@1895: SDL_SetError("Video subsystem has not been initialized"); slouken@1895: return -1; slouken@1895: } slouken@1895: palette = SDL_CurrentDisplay.palette; slouken@1895: if (!palette) { slouken@1895: SDL_SetError("Display mode does not have a palette"); slouken@1895: return -1; slouken@1895: } slouken@0: slouken@1895: status = SDL_SetPaletteColors(palette, colors, firstcolor, ncolors); slouken@0: slouken@1895: if (_this->SetDisplayPalette) { slouken@1895: if (_this->SetDisplayPalette(_this, palette) < 0) { slouken@1895: status = -1; slouken@1895: } slouken@1895: } slouken@1895: return status; slouken@0: } slouken@0: slouken@1895: int slouken@1895: SDL_GetDisplayPalette(SDL_Color * colors, int firstcolor, int ncolors) slouken@0: { slouken@1895: SDL_Palette *palette; slouken@1895: slouken@1895: if (!_this) { slouken@1895: SDL_SetError("Video subsystem has not been initialized"); slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: palette = SDL_CurrentDisplay.palette; slouken@1895: if (!palette->ncolors) { slouken@1895: SDL_SetError("Display mode does not have a palette"); slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: if (firstcolor < 0 || (firstcolor + ncolors) > palette->ncolors) { slouken@1895: SDL_SetError("Palette indices are out of range"); slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: SDL_memcpy(colors, &palette->colors[firstcolor], slouken@1895: ncolors * sizeof(*colors)); slouken@1895: return 0; slouken@0: } slouken@0: slouken@1895: SDL_WindowID slouken@1895: SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) slouken@0: { slouken@1895: const Uint32 allowed_flags = (SDL_WINDOW_FULLSCREEN | slouken@1895: SDL_WINDOW_OPENGL | slouken@1895: SDL_WINDOW_SHOWN | slouken@1895: SDL_WINDOW_BORDERLESS | slouken@1895: SDL_WINDOW_RESIZABLE | slouken@1895: SDL_WINDOW_MAXIMIZED | slouken@1895: SDL_WINDOW_MINIMIZED | slouken@1895: SDL_WINDOW_INPUT_GRABBED); slouken@1895: SDL_VideoDisplay *display; slouken@1895: SDL_Window window; slouken@1895: int num_windows; slouken@1895: SDL_Window *windows; slouken@0: slouken@1895: if (!_this) { slouken@1895: SDL_SetError("Video subsystem has not been initialized"); slouken@1895: return 0; slouken@1895: } slouken@0: slouken@1895: SDL_zero(window); slouken@1895: window.id = _this->next_object_id++; slouken@1895: window.title = title ? SDL_strdup(title) : NULL; slouken@1895: window.x = x; slouken@1895: window.y = y; slouken@1895: window.w = w; slouken@1895: window.h = h; slouken@1895: window.flags = (flags & allowed_flags); slouken@1895: window.display = _this->current_display; slouken@0: slouken@1895: if (_this->CreateWindow && _this->CreateWindow(_this, &window) < 0) { slouken@1895: if (window.title) { slouken@1895: SDL_free(window.title); slouken@1895: } slouken@1895: return 0; slouken@1895: } slouken@0: slouken@1895: display = &SDL_CurrentDisplay; slouken@1895: num_windows = display->num_windows; slouken@1895: windows = slouken@1895: SDL_realloc(display->windows, (num_windows + 1) * sizeof(*windows)); slouken@1895: if (!windows) { slouken@1895: if (_this->DestroyWindow) { slouken@1895: _this->DestroyWindow(_this, &window); slouken@1895: } slouken@1895: if (window.title) { slouken@1895: SDL_free(window.title); slouken@1895: } slouken@1895: return 0; slouken@1895: } slouken@1895: windows[num_windows] = window; slouken@1895: display->windows = windows; slouken@1895: display->num_windows++; slouken@0: slouken@1895: if (FULLSCREEN_VISIBLE(&window)) { slouken@1895: /* Hide any other fullscreen windows */ slouken@1895: int i; slouken@1895: for (i = 0; i < display->num_windows; ++i) { slouken@1895: SDL_Window *other = &display->windows[i]; slouken@1895: if (other->id != window.id && FULLSCREEN_VISIBLE(other)) { slouken@1895: SDL_MinimizeWindow(other->id); slouken@1895: } slouken@1895: } slouken@1895: SDL_SetDisplayMode(display->fullscreen_mode); slouken@1895: } slouken@0: slouken@1895: return window.id; slouken@1895: } slouken@0: slouken@1895: SDL_WindowID slouken@1895: SDL_CreateWindowFrom(const void *data) slouken@1895: { slouken@1895: SDL_VideoDisplay *display; slouken@1895: SDL_Window window; slouken@1895: int num_windows; slouken@1895: SDL_Window *windows; slouken@0: slouken@1895: if (!_this) { slouken@1895: SDL_SetError("Video subsystem has not been initialized"); slouken@1895: return (0); slouken@1895: } slouken@1895: slouken@1895: SDL_zero(window); slouken@1895: window.id = _this->next_object_id++; slouken@1895: window.display = _this->current_display; slouken@1895: slouken@1895: if (!_this->CreateWindowFrom || slouken@1895: _this->CreateWindowFrom(_this, &window, data) < 0) { slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: display = &SDL_CurrentDisplay; slouken@1895: num_windows = display->num_windows; slouken@1895: windows = slouken@1895: SDL_realloc(display->windows, (num_windows + 1) * sizeof(*windows)); slouken@1895: if (!windows) { slouken@1895: if (_this->DestroyWindow) { slouken@1895: _this->DestroyWindow(_this, &window); slouken@1895: } slouken@1895: if (window.title) { slouken@1895: SDL_free(window.title); slouken@1895: } slouken@1895: return 0; slouken@1895: } slouken@1895: windows[num_windows] = window; slouken@1895: display->windows = windows; slouken@1895: display->num_windows++; slouken@1895: slouken@1895: return window.id; slouken@1895: } slouken@1895: slouken@1895: SDL_Window * slouken@1895: SDL_GetWindowFromID(SDL_WindowID windowID) slouken@1895: { slouken@1895: int i, j; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return NULL; slouken@1895: } slouken@1895: slouken@1895: for (i = 0; i < _this->num_displays; ++i) { slouken@1895: SDL_VideoDisplay *display = &_this->displays[i]; slouken@1895: for (j = 0; j < display->num_windows; ++j) { slouken@1895: SDL_Window *window = &display->windows[j]; slouken@1895: if (window->id == windowID) { slouken@1895: return window; slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: return NULL; slouken@1895: } slouken@1895: slouken@1895: SDL_VideoDisplay * slouken@1895: SDL_GetDisplayFromWindow(SDL_Window * window) slouken@1895: { slouken@1895: if (!_this) { slouken@1895: return NULL; slouken@1895: } slouken@1895: return &_this->displays[window->display]; slouken@1895: } slouken@1895: slouken@1895: Uint32 slouken@1895: SDL_GetWindowFlags(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return 0; slouken@1895: } slouken@1895: return window->flags; slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_SetWindowTitle(SDL_WindowID windowID, const char *title) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return; slouken@1895: } slouken@1895: if (window->title) { slouken@1895: SDL_free(window->title); slouken@1895: } slouken@1895: window->title = SDL_strdup(title); slouken@1895: slouken@1895: if (_this->SetWindowTitle) { slouken@1895: _this->SetWindowTitle(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: const char * slouken@1895: SDL_GetWindowTitle(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return NULL; slouken@1895: } slouken@1895: return window->title; slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_SetWindowData(SDL_WindowID windowID, void *userdata) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return; slouken@1895: } slouken@1895: window->userdata = userdata; slouken@1895: } slouken@1895: slouken@1895: void * slouken@1895: SDL_GetWindowData(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return NULL; slouken@1895: } slouken@1895: return window->userdata; slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_SetWindowPosition(SDL_WindowID windowID, int x, int y) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: if (x != SDL_WINDOWPOS_UNDEFINED) { slouken@1895: window->x = x; slouken@1895: } slouken@1895: if (y != SDL_WINDOWPOS_UNDEFINED) { slouken@1895: window->y = y; slouken@1895: } slouken@1895: slouken@1895: if (_this->SetWindowPosition) { slouken@1895: _this->SetWindowPosition(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_GetWindowPosition(SDL_WindowID windowID, int *x, int *y) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return; slouken@1895: } slouken@1895: if (x) { slouken@1895: *x = window->x; slouken@1895: } slouken@1895: if (y) { slouken@1895: *y = window->y; slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_SetWindowSize(SDL_WindowID windowID, int w, int h) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: window->w = w; slouken@1895: window->h = h; slouken@1895: slouken@1895: if (_this->SetWindowSize) { slouken@1895: _this->SetWindowSize(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_GetWindowSize(SDL_WindowID windowID, int *w, int *h) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return; slouken@1895: } slouken@1895: if (w) { slouken@1895: *w = window->w; slouken@1895: } slouken@1895: if (h) { slouken@1895: *h = window->h; slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_ShowWindow(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window || (window->flags & SDL_WINDOW_SHOWN)) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_SHOWN, 0, 0); slouken@1895: slouken@1895: if (_this->ShowWindow) { slouken@1895: _this->ShowWindow(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_HideWindow(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window || !(window->flags & SDL_WINDOW_SHOWN)) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_HIDDEN, 0, 0); slouken@1895: slouken@1895: if (_this->HideWindow) { slouken@1895: _this->HideWindow(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_RaiseWindow(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: if (_this->RaiseWindow) { slouken@1895: _this->RaiseWindow(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_MaximizeWindow(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window || (window->flags & SDL_WINDOW_MAXIMIZED)) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MAXIMIZED, 0, 0); slouken@1895: slouken@1895: if (_this->MaximizeWindow) { slouken@1895: _this->MaximizeWindow(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_MinimizeWindow(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window || (window->flags & SDL_WINDOW_MINIMIZED)) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MINIMIZED, 0, 0); slouken@1895: slouken@1895: if (_this->MinimizeWindow) { slouken@1895: _this->MinimizeWindow(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_RestoreWindow(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window slouken@1895: || (window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_RESTORED, 0, 0); slouken@1895: slouken@1895: if (_this->RestoreWindow) { slouken@1895: _this->RestoreWindow(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_SetWindowFullscreen(SDL_WindowID windowID, int fullscreen) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: if (fullscreen) { slouken@1895: fullscreen = SDL_WINDOW_FULLSCREEN; slouken@1895: } slouken@1895: if ((window->flags & SDL_WINDOW_FULLSCREEN) == fullscreen) { slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: if (fullscreen) { slouken@1895: window->flags |= SDL_WINDOW_FULLSCREEN; slouken@1895: slouken@1895: if (FULLSCREEN_VISIBLE(window)) { slouken@1895: SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); slouken@1895: slouken@1895: /* Hide any other fullscreen windows */ slouken@1895: int i; slouken@1895: for (i = 0; i < display->num_windows; ++i) { slouken@1895: SDL_Window *other = &display->windows[i]; slouken@1895: if (other->id != windowID && FULLSCREEN_VISIBLE(other)) { slouken@1895: SDL_MinimizeWindow(other->id); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: SDL_SetDisplayMode(display->fullscreen_mode); slouken@1895: } slouken@1895: } else { slouken@1895: window->flags &= ~SDL_WINDOW_FULLSCREEN; slouken@1895: slouken@1895: if (FULLSCREEN_VISIBLE(window)) { slouken@1895: SDL_SetDisplayMode(NULL); slouken@1895: } slouken@1895: } slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_SetWindowGrab(SDL_WindowID windowID, int mode) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window || (!!mode == !!(window->flags & SDL_WINDOW_INPUT_GRABBED))) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: if (mode) { slouken@1895: window->flags |= SDL_WINDOW_INPUT_GRABBED; slouken@1895: } else { slouken@1895: window->flags &= ~SDL_WINDOW_INPUT_GRABBED; slouken@1895: } slouken@1895: slouken@1895: if ((window->flags & SDL_WINDOW_INPUT_FOCUS) && _this->SetWindowGrab) { slouken@1895: _this->SetWindowGrab(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_GetWindowGrab(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: return ((window->flags & SDL_WINDOW_INPUT_GRABBED) != 0); slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_OnWindowShown(SDL_Window * window) slouken@1895: { slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_OnWindowHidden(SDL_Window * window) slouken@1895: { slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_OnWindowFocusGained(SDL_Window * window) slouken@1895: { slouken@1895: SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); slouken@1895: slouken@1895: if (window->flags & SDL_WINDOW_FULLSCREEN) { slouken@1895: SDL_SetDisplayMode(display->fullscreen_mode); slouken@1895: } slouken@1895: if (display->gamma && _this->SetDisplayGammaRamp) { slouken@1895: _this->SetDisplayGammaRamp(_this, display->gamma); slouken@1895: } slouken@1895: if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && _this->SetWindowGrab) { slouken@1895: _this->SetWindowGrab(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_OnWindowFocusLost(SDL_Window * window) slouken@1895: { slouken@1895: SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); slouken@1895: slouken@1895: if (window->flags & SDL_WINDOW_FULLSCREEN) { slouken@1895: SDL_MinimizeWindow(window->id); slouken@1895: SDL_SetDisplayMode(NULL); slouken@1895: } slouken@1895: if (display->gamma && _this->SetDisplayGammaRamp) { slouken@1895: _this->SetDisplayGammaRamp(_this, display->saved_gamma); slouken@1895: } slouken@1895: if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && _this->SetWindowGrab) { slouken@1895: _this->SetWindowGrab(_this, window); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: SDL_WindowID slouken@1895: SDL_GetFocusWindow(void) slouken@1895: { slouken@1895: SDL_VideoDisplay *display; slouken@1895: int i; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: display = &SDL_CurrentDisplay; slouken@1895: for (i = 0; i < display->num_windows; ++i) { slouken@1895: SDL_Window *window = &display->windows[i]; slouken@1895: slouken@1895: if (window->flags & SDL_WINDOW_INPUT_FOCUS) { slouken@1895: return window->id; slouken@1895: } slouken@1895: } slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_DestroyWindow(SDL_WindowID windowID) slouken@1895: { slouken@1895: int i, j; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: /* Restore video mode, etc. */ slouken@1895: SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); slouken@1895: slouken@1895: for (i = 0; i < _this->num_displays; ++i) { slouken@1895: SDL_VideoDisplay *display = &_this->displays[i]; slouken@1895: for (j = 0; j < display->num_windows; ++j) { slouken@1895: SDL_Window *window = &display->windows[j]; slouken@1895: if (window->id != windowID) { slouken@1895: continue; slouken@1895: } slouken@1895: if (window->renderer) { slouken@1895: SDL_DestroyRenderer(window->id); slouken@1895: } slouken@1895: if (_this->DestroyWindow) { slouken@1895: _this->DestroyWindow(_this, window); slouken@1895: } slouken@1895: if (window->title) { slouken@1895: SDL_free(window->title); slouken@1895: } slouken@1895: if (j != display->num_windows - 1) { slouken@1895: SDL_memcpy(&display->windows[i], slouken@1895: &display->windows[i + 1], slouken@1895: (display->num_windows - i - 1) * sizeof(*window)); slouken@1895: } slouken@1895: --display->num_windows; slouken@1895: return; slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_AddRenderDriver(int displayIndex, const SDL_RenderDriver * driver) slouken@1895: { slouken@1895: SDL_VideoDisplay *display = &_this->displays[displayIndex]; slouken@1895: SDL_RenderDriver *render_drivers; slouken@1895: slouken@1895: render_drivers = slouken@1895: SDL_realloc(display->render_drivers, slouken@1895: (display->num_render_drivers + slouken@1895: 1) * sizeof(*render_drivers)); slouken@1895: if (render_drivers) { slouken@1895: render_drivers[display->num_render_drivers] = *driver; slouken@1895: display->render_drivers = render_drivers; slouken@1895: display->num_render_drivers++; slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_GetNumRenderers(void) slouken@1895: { slouken@1895: if (_this) { slouken@1895: return SDL_CurrentDisplay.num_render_drivers; slouken@1895: } slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_GetRendererInfo(int index, SDL_RendererInfo * info) slouken@1895: { slouken@1895: if (index < 0 || index >= SDL_GetNumRenderers()) { slouken@1895: SDL_SetError("index must be in the range of 0 - %d", slouken@1895: SDL_GetNumRenderers() - 1); slouken@1895: return -1; slouken@1895: } slouken@1895: *info = SDL_CurrentDisplay.render_drivers[index].info; slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_CreateRenderer(SDL_WindowID windowID, int index, Uint32 flags) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window) { slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: if (index < 0) { slouken@1895: int n = SDL_GetNumRenderers(); slouken@1895: for (index = 0; index < n; ++index) { slouken@1895: SDL_RenderDriver *driver = slouken@1895: &SDL_CurrentDisplay.render_drivers[index]; slouken@1895: slouken@1895: /* Skip minimal drivers in automatic scans */ slouken@1895: if (!(flags & SDL_Renderer_Minimal) slouken@1895: && (driver->info.flags & SDL_Renderer_Minimal)) { slouken@1895: continue; slouken@1895: } slouken@1895: if ((driver->info.flags & flags) == flags) { slouken@1895: break; slouken@1895: } slouken@1895: } slouken@1895: if (index == n) { slouken@1895: SDL_SetError("Couldn't find matching render driver"); slouken@1895: return -1; slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: if (index >= SDL_GetNumRenderers()) { slouken@1895: SDL_SetError("index must be -1 or in the range of 0 - %d", slouken@1895: SDL_GetNumRenderers() - 1); slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: /* Free any existing renderer */ slouken@1895: SDL_DestroyRenderer(windowID); slouken@1895: slouken@1895: /* Create a new renderer instance */ slouken@1895: window->renderer = slouken@1895: SDL_CurrentDisplay.render_drivers[index].CreateRenderer(window, slouken@1895: flags); slouken@1895: if (!window->renderer) { slouken@1895: return -1; slouken@1895: } slouken@1895: SDL_CurrentDisplay.current_renderer = window->renderer; slouken@1895: slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_SelectRenderer(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window || !window->renderer) { slouken@1895: return -1; slouken@1895: } slouken@1895: SDL_CurrentDisplay.current_renderer = window->renderer; slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: SDL_TextureID slouken@1895: SDL_CreateTexture(Uint32 format, int access, int w, int h) slouken@1895: { slouken@1895: int hash; slouken@1895: SDL_Renderer *renderer; slouken@1895: SDL_Texture *texture; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: renderer = SDL_CurrentDisplay.current_renderer; slouken@1895: if (!renderer || !renderer->CreateTexture) { slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: texture = (SDL_Texture *) SDL_malloc(sizeof(*texture)); slouken@1895: if (!texture) { slouken@1895: SDL_OutOfMemory(); slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: SDL_zerop(texture); slouken@1895: texture->id = _this->next_object_id++; slouken@1895: texture->format = format; slouken@1895: texture->access = access; slouken@1895: texture->w = w; slouken@1895: texture->h = h; slouken@1895: texture->renderer = renderer; slouken@1895: slouken@1895: if (renderer->CreateTexture(renderer, texture) < 0) { slouken@1895: SDL_free(texture); slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: hash = (texture->id % SDL_arraysize(SDL_CurrentDisplay.textures)); slouken@1895: texture->next = SDL_CurrentDisplay.textures[hash]; slouken@1895: SDL_CurrentDisplay.textures[hash] = texture; slouken@1895: slouken@1895: return texture->id; slouken@1895: } slouken@1895: slouken@1895: SDL_TextureID slouken@1895: SDL_CreateTextureFromSurface(Uint32 format, int access, SDL_Surface * surface) slouken@1895: { slouken@1895: SDL_TextureID textureID; slouken@1895: Uint32 surface_flags = surface->flags; slouken@1895: SDL_PixelFormat *fmt = surface->format; slouken@1895: Uint8 alpha; slouken@1895: SDL_Rect bounds; slouken@1895: SDL_Surface dst; slouken@1895: int bpp; slouken@1895: Uint32 Rmask, Gmask, Bmask, Amask; slouken@1895: slouken@1895: if (!surface) { slouken@1895: SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: if (format) { slouken@1895: if (!SDL_PixelFormatEnumToMasks slouken@1895: (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { slouken@1895: SDL_SetError("Unknown pixel format"); slouken@1895: return 0; slouken@1895: } slouken@1895: } else { slouken@1895: if (fmt->Amask || !(surface_flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA))) { slouken@1895: bpp = fmt->BitsPerPixel; slouken@1895: Rmask = fmt->Rmask; slouken@1895: Gmask = fmt->Gmask; slouken@1895: Bmask = fmt->Bmask; slouken@1895: Amask = fmt->Amask; slouken@1895: } else { slouken@1895: /* Need a format with alpha */ slouken@1895: bpp = 32; slouken@1895: Rmask = 0x00FF0000; slouken@1895: Gmask = 0x0000FF00; slouken@1895: Bmask = 0x000000FF; slouken@1895: Amask = 0xFF000000; slouken@1895: } slouken@1895: format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask); slouken@1895: if (!format) { slouken@1895: SDL_SetError("Unknown pixel format"); slouken@1895: return 0; slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: textureID = SDL_CreateTexture(format, access, surface->w, surface->h); slouken@1895: if (!textureID) { slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: /* Set up a destination surface for the texture update */ slouken@1895: SDL_zero(dst); slouken@1895: dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); slouken@1895: if (!dst.format) { slouken@1895: SDL_DestroyTexture(textureID); slouken@1895: return 0; slouken@1895: } slouken@1895: dst.w = surface->w; slouken@1895: dst.h = surface->h; slouken@1895: if (SDL_LockTexture(textureID, NULL, 1, &dst.pixels, &dst.pitch) == 0) { slouken@1895: dst.flags |= SDL_PREALLOC; slouken@1895: } else { slouken@1895: dst.pitch = SDL_CalculatePitch(&dst); slouken@1895: dst.pixels = SDL_malloc(dst.h * dst.pitch); slouken@1895: if (!dst.pixels) { slouken@1895: SDL_DestroyTexture(textureID); slouken@1895: SDL_FreeFormat(dst.format); slouken@1895: SDL_OutOfMemory(); slouken@1895: return 0; slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: /* Copy the palette if any */ slouken@1895: if (SDL_ISPIXELFORMAT_INDEXED(format)) { slouken@1895: if (fmt->palette) { slouken@1895: SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, slouken@1895: fmt->palette->ncolors); slouken@1895: SDL_SetSurfacePalette(&dst, fmt->palette); slouken@1895: } else { slouken@1895: dst.format->palette = slouken@1895: SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format))); slouken@1895: if (!dst.format->palette) { slouken@1895: SDL_DestroyTexture(textureID); slouken@1895: SDL_FreeFormat(dst.format); slouken@1895: return 0; slouken@1895: } slouken@1895: SDL_DitherColors(dst.format->palette->colors, slouken@1895: SDL_BITSPERPIXEL(format)); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: /* Make the texture transparent if the surface has colorkey */ slouken@1895: if (surface_flags & SDL_SRCCOLORKEY) { slouken@1895: int row; slouken@1895: int length = dst.w * dst.format->BytesPerPixel; slouken@1895: Uint8 *p = (Uint8 *) dst.pixels; slouken@1895: for (row = 0; row < dst.h; ++row) { slouken@1895: SDL_memset(p, 0, length); slouken@1895: p += dst.pitch; slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: /* Copy over the alpha channel */ slouken@1895: if (surface_flags & SDL_SRCALPHA) { slouken@1895: if (fmt->Amask) { slouken@1895: surface->flags &= ~SDL_SRCALPHA; slouken@1895: } else { slouken@1895: /* FIXME: Need to make sure the texture has an alpha channel slouken@1895: * and copy 'alpha' into the texture alpha channel. slouken@1895: */ slouken@1895: alpha = surface->format->alpha; slouken@1895: SDL_SetAlpha(surface, 0, 0); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: /* Copy over the image data */ slouken@1895: bounds.x = 0; slouken@1895: bounds.y = 0; slouken@1895: bounds.w = surface->w; slouken@1895: bounds.h = surface->h; slouken@1895: SDL_LowerBlit(surface, &bounds, &dst, &bounds); slouken@1895: slouken@1895: /* Clean up the original surface */ slouken@1895: if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { slouken@1895: Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK); slouken@1895: if (fmt->Amask) { slouken@1895: surface->flags |= SDL_SRCALPHA; slouken@1895: } else { slouken@1895: SDL_SetAlpha(surface, aflags, alpha); slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: /* Update the texture */ slouken@1895: if (dst.flags & SDL_PREALLOC) { slouken@1895: SDL_UnlockTexture(textureID); slouken@1895: } else { slouken@1895: SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch); slouken@1895: SDL_free(dst.pixels); slouken@1895: } slouken@1895: SDL_FreeFormat(dst.format); slouken@1895: slouken@1895: return textureID; slouken@1895: } slouken@1895: slouken@1895: static __inline__ SDL_Texture * slouken@1895: SDL_GetTextureFromID(SDL_TextureID textureID) slouken@1895: { slouken@1895: int hash; slouken@1895: SDL_Texture *texture; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return NULL; slouken@1895: } slouken@1895: slouken@1895: hash = (textureID % SDL_arraysize(SDL_CurrentDisplay.textures)); slouken@1895: for (texture = SDL_CurrentDisplay.textures[hash]; texture; slouken@1895: texture = texture->next) { slouken@1895: if (texture->id == textureID) { slouken@1895: return texture; slouken@1895: } slouken@1895: } slouken@1895: return NULL; slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_QueryTexture(SDL_TextureID textureID, Uint32 * format, int *access, slouken@1895: int *w, int *h) slouken@1895: { slouken@1895: SDL_Texture *texture = SDL_GetTextureFromID(textureID); slouken@1895: slouken@1895: if (!texture) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: if (format) { slouken@1895: *format = texture->format; slouken@1895: } slouken@1895: if (access) { slouken@1895: *access = texture->access; slouken@1895: } slouken@1895: if (w) { slouken@1895: *w = texture->w; slouken@1895: } slouken@1895: if (h) { slouken@1895: *h = texture->h; slouken@1895: } slouken@1895: return 0; slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_QueryTexturePixels(SDL_TextureID textureID, void **pixels, int *pitch) slouken@1895: { slouken@1895: SDL_Texture *texture = SDL_GetTextureFromID(textureID); slouken@1895: SDL_Renderer *renderer; slouken@1895: slouken@1895: if (!texture) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: renderer = texture->renderer; slouken@1895: if (!renderer->QueryTexturePixels) { slouken@1895: return -1; slouken@1895: } slouken@1895: return renderer->QueryTexturePixels(renderer, texture, pixels, pitch); slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_SetTexturePalette(SDL_TextureID textureID, const SDL_Color * colors, slouken@1895: int firstcolor, int ncolors) slouken@1895: { slouken@1895: SDL_Texture *texture = SDL_GetTextureFromID(textureID); slouken@1895: SDL_Renderer *renderer; slouken@1895: slouken@1895: if (!texture) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: renderer = texture->renderer; slouken@1895: if (!renderer->SetTexturePalette) { slouken@1895: return -1; slouken@1895: } slouken@1895: return renderer->SetTexturePalette(renderer, texture, colors, firstcolor, slouken@1895: ncolors); slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_GetTexturePalette(SDL_TextureID textureID, SDL_Color * colors, slouken@1895: int firstcolor, int ncolors) slouken@1895: { slouken@1895: SDL_Texture *texture = SDL_GetTextureFromID(textureID); slouken@1895: SDL_Renderer *renderer; slouken@1895: slouken@1895: if (!texture) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: renderer = texture->renderer; slouken@1895: if (!renderer->GetTexturePalette) { slouken@1895: return -1; slouken@1895: } slouken@1895: return renderer->GetTexturePalette(renderer, texture, colors, firstcolor, slouken@1895: ncolors); slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_UpdateTexture(SDL_TextureID textureID, const SDL_Rect * rect, slouken@1895: const void *pixels, int pitch) slouken@1895: { slouken@1895: SDL_Texture *texture = SDL_GetTextureFromID(textureID); slouken@1895: SDL_Renderer *renderer; slouken@1895: SDL_Rect full_rect; slouken@1895: slouken@1895: if (!texture) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: renderer = texture->renderer; slouken@1895: if (!renderer->UpdateTexture) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: if (!rect) { slouken@1895: full_rect.x = 0; slouken@1895: full_rect.y = 0; slouken@1895: full_rect.w = texture->w; slouken@1895: full_rect.h = texture->h; slouken@1895: rect = &full_rect; slouken@1895: } slouken@1895: slouken@1895: return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch); slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_LockTexture(SDL_TextureID textureID, const SDL_Rect * rect, int markDirty, slouken@1895: void **pixels, int *pitch) slouken@1895: { slouken@1895: SDL_Texture *texture = SDL_GetTextureFromID(textureID); slouken@1895: SDL_Renderer *renderer; slouken@1895: SDL_Rect full_rect; slouken@1895: slouken@1895: if (!texture) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: renderer = texture->renderer; slouken@1895: if (!renderer->LockTexture) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: if (!rect) { slouken@1895: full_rect.x = 0; slouken@1895: full_rect.y = 0; slouken@1895: full_rect.w = texture->w; slouken@1895: full_rect.h = texture->h; slouken@1895: rect = &full_rect; slouken@1895: } slouken@1895: slouken@1895: return renderer->LockTexture(renderer, texture, rect, markDirty, pixels, slouken@1895: pitch); slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_UnlockTexture(SDL_TextureID textureID) slouken@1895: { slouken@1895: SDL_Texture *texture = SDL_GetTextureFromID(textureID); slouken@1895: SDL_Renderer *renderer; slouken@1895: slouken@1895: if (!texture) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: renderer = texture->renderer; slouken@1895: if (!renderer->UnlockTexture) { slouken@1895: return; slouken@1895: } slouken@1895: renderer->UnlockTexture(renderer, texture); slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_DirtyTexture(SDL_TextureID textureID, int numrects, slouken@1895: const SDL_Rect * rects) slouken@1895: { slouken@1895: SDL_Texture *texture = SDL_GetTextureFromID(textureID); slouken@1895: SDL_Renderer *renderer; slouken@1895: slouken@1895: if (!texture) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: renderer = texture->renderer; slouken@1895: if (!renderer->DirtyTexture) { slouken@1895: return; slouken@1895: } slouken@1895: renderer->DirtyTexture(renderer, texture, numrects, rects); slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_SelectRenderTexture(SDL_TextureID textureID) slouken@1895: { slouken@1895: SDL_Texture *texture = SDL_GetTextureFromID(textureID); slouken@1895: SDL_Renderer *renderer; slouken@1895: slouken@1895: if (!texture || texture->access != SDL_TextureAccess_Render) { slouken@1895: return; slouken@1895: } slouken@1895: renderer = texture->renderer; slouken@1895: if (!renderer->SelectRenderTexture) { slouken@1895: return; slouken@1895: } slouken@1895: renderer->SelectRenderTexture(renderer, texture); slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_RenderFill(const SDL_Rect * rect, Uint32 color) slouken@1895: { slouken@1895: SDL_Renderer *renderer; slouken@1895: SDL_Window *window; slouken@1895: SDL_Rect real_rect; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: renderer = SDL_CurrentDisplay.current_renderer; slouken@1895: if (!renderer || !renderer->RenderFill) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: window = SDL_GetWindowFromID(renderer->window); slouken@1895: real_rect.x = 0; slouken@1895: real_rect.y = 0; slouken@1895: real_rect.w = window->w; slouken@1895: real_rect.h = window->h; slouken@1895: if (rect) { slouken@1895: if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) { slouken@1895: return 0; slouken@1895: } slouken@1895: } slouken@1895: slouken@1897: return renderer->RenderFill(renderer, &real_rect, color); slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_RenderCopy(SDL_TextureID textureID, const SDL_Rect * srcrect, slouken@1895: const SDL_Rect * dstrect, int blendMode, int scaleMode) slouken@1895: { slouken@1895: SDL_Texture *texture = SDL_GetTextureFromID(textureID); slouken@1895: SDL_Renderer *renderer; slouken@1895: SDL_Window *window; slouken@1895: SDL_Rect real_srcrect; slouken@1895: SDL_Rect real_dstrect; slouken@1895: slouken@1895: if (!texture || texture->renderer != SDL_CurrentDisplay.current_renderer) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: renderer = SDL_CurrentDisplay.current_renderer; slouken@1895: if (!renderer || !renderer->RenderCopy) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: window = SDL_GetWindowFromID(renderer->window); slouken@1897: if (srcrect) { slouken@1897: real_srcrect = *srcrect; slouken@1897: } else { slouken@1897: real_srcrect.x = 0; slouken@1897: real_srcrect.y = 0; slouken@1897: real_srcrect.w = texture->w; slouken@1897: real_srcrect.h = texture->h; slouken@1895: } slouken@1897: if (dstrect) { slouken@1897: real_dstrect = *dstrect; slouken@1897: } else { slouken@1897: real_dstrect.x = 0; slouken@1897: real_dstrect.y = 0; slouken@1897: real_dstrect.w = window->w; slouken@1897: real_dstrect.h = window->h; slouken@1895: } slouken@1895: slouken@1897: return renderer->RenderCopy(renderer, texture, &real_srcrect, slouken@1897: &real_dstrect, blendMode, scaleMode); slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_RenderReadPixels(const SDL_Rect * rect, void *pixels, int pitch) slouken@1895: { slouken@1895: SDL_Renderer *renderer; slouken@1895: SDL_Rect full_rect; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: renderer = SDL_CurrentDisplay.current_renderer; slouken@1895: if (!renderer || !renderer->RenderReadPixels) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: if (!rect) { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(renderer->window); slouken@1895: full_rect.x = 0; slouken@1895: full_rect.y = 0; slouken@1895: full_rect.w = window->w; slouken@1895: full_rect.h = window->h; slouken@1895: rect = &full_rect; slouken@1895: } slouken@1895: slouken@1895: return renderer->RenderReadPixels(renderer, rect, pixels, pitch); slouken@1895: } slouken@1895: slouken@1895: int slouken@1895: SDL_RenderWritePixels(const SDL_Rect * rect, const void *pixels, int pitch) slouken@1895: { slouken@1895: SDL_Renderer *renderer; slouken@1895: SDL_Rect full_rect; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: renderer = SDL_CurrentDisplay.current_renderer; slouken@1895: if (!renderer || !renderer->RenderWritePixels) { slouken@1895: return -1; slouken@1895: } slouken@1895: slouken@1895: if (!rect) { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(renderer->window); slouken@1895: full_rect.x = 0; slouken@1895: full_rect.y = 0; slouken@1895: full_rect.w = window->w; slouken@1895: full_rect.h = window->h; slouken@1895: rect = &full_rect; slouken@1895: } slouken@1895: slouken@1895: return renderer->RenderWritePixels(renderer, rect, pixels, pitch); slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_RenderPresent(void) slouken@1895: { slouken@1895: SDL_Renderer *renderer; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: renderer = SDL_CurrentDisplay.current_renderer; slouken@1895: if (!renderer || !renderer->RenderPresent) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1897: if (renderer->SelectRenderTexture) { slouken@1897: renderer->SelectRenderTexture(renderer, NULL); slouken@1897: } slouken@1895: renderer->RenderPresent(renderer); slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_DestroyTexture(SDL_TextureID textureID) slouken@1895: { slouken@1895: int hash; slouken@1895: SDL_Texture *prev, *texture; slouken@1895: SDL_Renderer *renderer; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: /* Look up the texture in the hash table */ slouken@1895: hash = (textureID % SDL_arraysize(SDL_CurrentDisplay.textures)); slouken@1895: prev = NULL; slouken@1895: for (texture = SDL_CurrentDisplay.textures[hash]; texture; slouken@1895: prev = texture, texture = texture->next) { slouken@1895: if (texture->id == textureID) { slouken@1895: break; slouken@1895: } slouken@1895: } slouken@1895: if (!texture) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: /* Unlink the texture from the list */ slouken@1895: if (prev) { slouken@1895: prev->next = texture->next; slouken@1895: } else { slouken@1895: SDL_CurrentDisplay.textures[hash] = texture->next; slouken@1895: } slouken@1895: slouken@1895: /* Free the texture */ slouken@1895: renderer = texture->renderer; slouken@1895: renderer->DestroyTexture(renderer, texture); slouken@1895: SDL_free(texture); slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_DestroyRenderer(SDL_WindowID windowID) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: SDL_Renderer *renderer; slouken@1895: int i; slouken@1895: slouken@1895: if (!window) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: renderer = window->renderer; slouken@1895: if (!renderer) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: /* Free existing textures for this renderer */ slouken@1895: for (i = 0; i < SDL_arraysize(SDL_CurrentDisplay.textures); ++i) { slouken@1895: SDL_Texture *texture; slouken@1895: SDL_Texture *prev = NULL; slouken@1895: SDL_Texture *next; slouken@1895: for (texture = SDL_CurrentDisplay.textures[i]; texture; slouken@1895: texture = next) { slouken@1895: next = texture->next; slouken@1895: if (texture->renderer == renderer) { slouken@1895: if (prev) { slouken@1895: prev->next = next; slouken@1895: } else { slouken@1895: SDL_CurrentDisplay.textures[i] = next; slouken@1895: } slouken@1895: renderer->DestroyTexture(renderer, texture); slouken@1895: SDL_free(texture); slouken@1895: } else { slouken@1895: prev = texture; slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: /* Free the renderer instance */ slouken@1895: renderer->DestroyRenderer(renderer); slouken@1895: slouken@1895: /* Clear references */ slouken@1895: window->renderer = NULL; slouken@1895: if (SDL_CurrentDisplay.current_renderer == renderer) { slouken@1895: SDL_CurrentDisplay.current_renderer = NULL; slouken@1895: } slouken@1895: } slouken@1895: slouken@1895: void slouken@1895: SDL_VideoQuit(void) slouken@1895: { slouken@1895: int i, j; slouken@1895: slouken@1895: if (!_this) { slouken@1895: return; slouken@1895: } slouken@1895: slouken@1895: /* Halt event processing before doing anything else */ slouken@1895: SDL_StopEventLoop(); slouken@1895: slouken@1895: /* Clean up the system video */ slouken@1895: for (i = _this->num_displays; i--;) { slouken@1895: SDL_VideoDisplay *display = &_this->displays[i]; slouken@1895: for (j = display->num_windows; j--;) { slouken@1895: SDL_DestroyWindow(display->windows[i].id); slouken@1895: } slouken@1895: if (display->windows) { slouken@1895: SDL_free(display->windows); slouken@1895: display->windows = NULL; slouken@1895: } slouken@1895: display->num_windows = 0; slouken@1895: } slouken@1895: _this->VideoQuit(_this); slouken@1895: slouken@1895: for (i = _this->num_displays; i--;) { slouken@1895: SDL_VideoDisplay *display = &_this->displays[i]; slouken@1895: for (j = display->num_display_modes; j--;) { slouken@1895: if (display->display_modes[j].driverdata) { slouken@1895: SDL_free(display->display_modes[j].driverdata); slouken@1895: display->display_modes[j].driverdata = NULL; slouken@1895: } slouken@1895: } slouken@1895: if (display->display_modes) { slouken@1895: SDL_free(display->display_modes); slouken@1895: display->display_modes = NULL; slouken@1895: } slouken@1895: if (display->desktop_mode.driverdata) { slouken@1895: SDL_free(display->desktop_mode.driverdata); slouken@1895: display->desktop_mode.driverdata = NULL; slouken@1895: } slouken@1895: if (display->palette) { slouken@1895: SDL_FreePalette(display->palette); slouken@1895: display->palette = NULL; slouken@1895: } slouken@1895: if (display->gamma) { slouken@1895: SDL_free(display->gamma); slouken@1895: } slouken@1895: if (display->driverdata) { slouken@1895: SDL_free(display->driverdata); slouken@1895: } slouken@1895: } slouken@1895: if (_this->displays) { slouken@1895: SDL_free(_this->displays); slouken@1895: _this->displays = NULL; slouken@1895: } slouken@1895: _this->free(_this); slouken@1895: _this = NULL; slouken@0: } slouken@0: slouken@0: /* Load the GL driver library */ slouken@1895: int slouken@1895: SDL_GL_LoadLibrary(const char *path) slouken@0: { slouken@1895: int retval; slouken@0: slouken@1895: retval = -1; slouken@1895: if (_this == NULL) { slouken@1895: SDL_SetError("Video subsystem has not been initialized"); slouken@1895: } else { slouken@1895: if (_this->GL_LoadLibrary) { slouken@1895: retval = _this->GL_LoadLibrary(_this, path); slouken@1895: } else { slouken@1895: SDL_SetError("No dynamic GL support in video driver"); slouken@1895: } slouken@1895: } slouken@1895: return (retval); slouken@0: } slouken@0: slouken@1895: void * slouken@1895: SDL_GL_GetProcAddress(const char *proc) slouken@0: { slouken@1895: void *func; slouken@0: slouken@1895: func = NULL; slouken@1895: if (_this->GL_GetProcAddress) { slouken@1895: if (_this->gl_config.driver_loaded) { slouken@1895: func = _this->GL_GetProcAddress(_this, proc); slouken@1895: } else { slouken@1895: SDL_SetError("No GL driver has been loaded"); slouken@1895: } slouken@1895: } else { slouken@1895: SDL_SetError("No dynamic GL support in video driver"); slouken@1895: } slouken@1895: return func; slouken@0: } slouken@0: slouken@0: /* Set the specified GL attribute for setting up a GL video mode */ slouken@1895: int slouken@1895: SDL_GL_SetAttribute(SDL_GLattr attr, int value) slouken@0: { slouken@1895: int retval; slouken@0: slouken@1895: retval = 0; slouken@1895: switch (attr) { slouken@1895: case SDL_GL_RED_SIZE: slouken@1895: _this->gl_config.red_size = value; slouken@1895: break; slouken@1895: case SDL_GL_GREEN_SIZE: slouken@1895: _this->gl_config.green_size = value; slouken@1895: break; slouken@1895: case SDL_GL_BLUE_SIZE: slouken@1895: _this->gl_config.blue_size = value; slouken@1895: break; slouken@1895: case SDL_GL_ALPHA_SIZE: slouken@1895: _this->gl_config.alpha_size = value; slouken@1895: break; slouken@1895: case SDL_GL_DOUBLEBUFFER: slouken@1895: _this->gl_config.double_buffer = value; slouken@1895: break; slouken@1895: case SDL_GL_BUFFER_SIZE: slouken@1895: _this->gl_config.buffer_size = value; slouken@1895: break; slouken@1895: case SDL_GL_DEPTH_SIZE: slouken@1895: _this->gl_config.depth_size = value; slouken@1895: break; slouken@1895: case SDL_GL_STENCIL_SIZE: slouken@1895: _this->gl_config.stencil_size = value; slouken@1895: break; slouken@1895: case SDL_GL_ACCUM_RED_SIZE: slouken@1895: _this->gl_config.accum_red_size = value; slouken@1895: break; slouken@1895: case SDL_GL_ACCUM_GREEN_SIZE: slouken@1895: _this->gl_config.accum_green_size = value; slouken@1895: break; slouken@1895: case SDL_GL_ACCUM_BLUE_SIZE: slouken@1895: _this->gl_config.accum_blue_size = value; slouken@1895: break; slouken@1895: case SDL_GL_ACCUM_ALPHA_SIZE: slouken@1895: _this->gl_config.accum_alpha_size = value; slouken@1895: break; slouken@1895: case SDL_GL_STEREO: slouken@1895: _this->gl_config.stereo = value; slouken@1895: break; slouken@1895: case SDL_GL_MULTISAMPLEBUFFERS: slouken@1895: _this->gl_config.multisamplebuffers = value; slouken@1895: break; slouken@1895: case SDL_GL_MULTISAMPLESAMPLES: slouken@1895: _this->gl_config.multisamplesamples = value; slouken@1895: break; slouken@1895: case SDL_GL_ACCELERATED_VISUAL: slouken@1895: _this->gl_config.accelerated = value; slouken@1895: break; slouken@1895: default: slouken@1895: SDL_SetError("Unknown OpenGL attribute"); slouken@1895: retval = -1; slouken@1895: break; slouken@1895: } slouken@1895: return (retval); slouken@0: } slouken@0: slouken@0: /* Retrieve an attribute value from the windowing system. */ slouken@1895: int slouken@1895: SDL_GL_GetAttribute(SDL_GLattr attr, int *value) slouken@0: { slouken@1895: int retval = -1; slouken@0: slouken@1895: if (_this->GL_GetAttribute) { slouken@1895: retval = _this->GL_GetAttribute(_this, attr, value); slouken@1895: } else { slouken@1895: *value = 0; slouken@1895: SDL_SetError("GL_GetAttribute not supported"); slouken@1895: } slouken@1895: return retval; slouken@0: } slouken@0: slouken@0: /* Perform a GL buffer swap on the current GL context */ slouken@1895: void slouken@1895: SDL_GL_SwapBuffers(void) slouken@0: { slouken@1895: // FIXME: Track the current window context - do we provide N contexts, and match them to M windows, or is there a one-to-one mapping? slouken@1895: _this->GL_SwapBuffers(_this); slouken@0: } slouken@0: slouken@1895: #if 0 // FIXME slouken@541: /* Utility function used by SDL_WM_SetIcon(); slouken@541: * flags & 1 for color key, flags & 2 for alpha channel. */ slouken@1895: static void slouken@1895: CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon, Uint8 * mask, int flags) slouken@0: { slouken@1895: int x, y; slouken@1895: Uint32 colorkey; slouken@0: #define SET_MASKBIT(icon, x, y, mask) \ slouken@0: mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8))) slouken@0: slouken@1895: colorkey = icon->format->colorkey; slouken@1895: switch (icon->format->BytesPerPixel) { slouken@1895: case 1: slouken@1895: { slouken@1895: Uint8 *pixels; slouken@1895: for (y = 0; y < icon->h; ++y) { slouken@1895: pixels = (Uint8 *) icon->pixels + y * icon->pitch; slouken@1895: for (x = 0; x < icon->w; ++x) { slouken@1895: if (*pixels++ == colorkey) { slouken@1895: SET_MASKBIT(icon, x, y, mask); slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: break; slouken@0: slouken@1895: case 2: slouken@1895: { slouken@1895: Uint16 *pixels; slouken@1895: for (y = 0; y < icon->h; ++y) { slouken@1895: pixels = (Uint16 *) icon->pixels + y * icon->pitch / 2; slouken@1895: for (x = 0; x < icon->w; ++x) { slouken@1895: if ((flags & 1) && *pixels == colorkey) { slouken@1895: SET_MASKBIT(icon, x, y, mask); slouken@1895: } else if ((flags & 2) slouken@1895: && (*pixels & icon->format->Amask) == 0) { slouken@1895: SET_MASKBIT(icon, x, y, mask); slouken@1895: } slouken@1895: pixels++; slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: break; slouken@0: slouken@1895: case 4: slouken@1895: { slouken@1895: Uint32 *pixels; slouken@1895: for (y = 0; y < icon->h; ++y) { slouken@1895: pixels = (Uint32 *) icon->pixels + y * icon->pitch / 4; slouken@1895: for (x = 0; x < icon->w; ++x) { slouken@1895: if ((flags & 1) && *pixels == colorkey) { slouken@1895: SET_MASKBIT(icon, x, y, mask); slouken@1895: } else if ((flags & 2) slouken@1895: && (*pixels & icon->format->Amask) == 0) { slouken@1895: SET_MASKBIT(icon, x, y, mask); slouken@1895: } slouken@1895: pixels++; slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: break; slouken@1895: } slouken@0: } slouken@0: slouken@0: /* slouken@0: * Sets the window manager icon for the display window. slouken@0: */ slouken@1895: void slouken@1895: SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask) slouken@0: { slouken@1895: if (icon && _this->SetIcon) { slouken@1895: /* Generate a mask if necessary, and create the icon! */ slouken@1895: if (mask == NULL) { slouken@1895: int mask_len = icon->h * (icon->w + 7) / 8; slouken@1895: int flags = 0; slouken@1895: mask = (Uint8 *) SDL_malloc(mask_len); slouken@1895: if (mask == NULL) { slouken@1895: return; slouken@1895: } slouken@1895: SDL_memset(mask, ~0, mask_len); slouken@1895: if (icon->flags & SDL_SRCCOLORKEY) slouken@1895: flags |= 1; slouken@1895: if (icon->flags & SDL_SRCALPHA) slouken@1895: flags |= 2; slouken@1895: if (flags) { slouken@1895: CreateMaskFromColorKeyOrAlpha(icon, mask, flags); slouken@1895: } slouken@1895: _this->SetIcon(_this, icon, mask); slouken@1895: SDL_free(mask); slouken@1895: } else { slouken@1895: _this->SetIcon(_this, icon, mask); slouken@1895: } slouken@1895: } slouken@1895: } slouken@1895: #endif slouken@0: slouken@1895: SDL_bool slouken@1895: SDL_GetWindowWMInfo(SDL_WindowID windowID, struct SDL_SysWMinfo *info) slouken@1895: { slouken@1895: SDL_Window *window = SDL_GetWindowFromID(windowID); slouken@1895: slouken@1895: if (!window || !_this->GetWindowWMInfo) { slouken@1895: return SDL_FALSE; slouken@1895: } slouken@1895: return (_this->GetWindowWMInfo(_this, window, info)); slouken@0: } slouken@0: slouken@1895: /* vi: set ts=4 sw=4 expandtab: */