void SDL2Window::changeMode(DisplayMode mode, bool makeFullscreen) { if(!m_window) { m_size = mode.resolution; m_fullscreen = makeFullscreen; return; } if(m_fullscreen == makeFullscreen && m_size == mode.resolution) { return; } bool wasFullscreen = m_fullscreen; m_renderer->beforeResize(wasFullscreen || makeFullscreen); if(makeFullscreen) { if(mode.resolution != Vec2i_ZERO) { SDL_DisplayMode sdlmode; SDL_DisplayMode requested; requested.driverdata = NULL; requested.format = 0; requested.refresh_rate = 0; requested.w = mode.resolution.x; requested.h = mode.resolution.y; int display = SDL_GetWindowDisplayIndex(m_window); if(!SDL_GetClosestDisplayMode(display, &requested, &sdlmode)) { if(SDL_GetDesktopDisplayMode(display, &sdlmode)) { return; } } if(SDL_SetWindowDisplayMode(m_window, &sdlmode) < 0) { return; } } } Uint32 flags = getSDLFlagsForMode(mode.resolution, makeFullscreen); if(SDL_SetWindowFullscreen(m_window, flags) < 0) { return; } if(!makeFullscreen) { SDL_SetWindowSize(m_window, mode.resolution.x, mode.resolution.y); } if(wasFullscreen != makeFullscreen) { onToggleFullscreen(makeFullscreen); } if(makeFullscreen) { // SDL regrettably sends resize events when a fullscreen window is minimized. // Because of that we ignore all size change events when fullscreen. // Instead, handle the size change here. updateSize(); } tick(); }
SGL_Window* SGL_CreateWindow(const char* title, int GLMajorVersion, int GLMinorVersion, int x, int y, int w, int h, Uint32 SDLflags) { #if defined(_WINDOWS) SDL_DisplayMode targetMode; if (SDL_GetCurrentDisplayMode(0, &targetMode)) { return NULL; } SDL_DisplayMode closestMode; SDL_GetClosestDisplayMode(0, &targetMode, &closestMode); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, GLMajorVersion); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, GLMinorVersion); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SGL_Window* window = SDL_malloc(sizeof(SGL_Window)); window->window = SDL_CreateWindow ( title, x, y, w, h, SDLflags ); window->context = SDL_GL_CreateContext(window->window); glewExperimental = GL_TRUE; glewInit(); #elif defined(ANDROID) SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, GLMajorVersion > 3 ? GLMajorVersion : 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SGL_Window* window = SDL_malloc(sizeof(SGL_Window)); SDL_DisplayMode displayMode; if (SDL_GetCurrentDisplayMode(0, &displayMode)) { return NULL; } window->window = SDL_CreateWindow ( title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, displayMode.w, displayMode.h, SDLflags ); window->context = SDL_GL_CreateContext(window->window); #endif SDL_Log("----------------------------------------------------------------\n"); SDL_Log("Graphics Successfully Initialized For Window: %s\n", title); SDL_Log("OpenGL Info\n"); SDL_Log(" Version: %s\n", glGetString(GL_VERSION)); SDL_Log(" Vendor: %s\n", glGetString(GL_VENDOR)); SDL_Log(" Renderer: %s\n", glGetString(GL_RENDERER)); SDL_Log(" Shading: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); SDL_Log("----------------------------------------------------------------\n"); SGL_SetWindowIcon(window, NULL); return window; }
static void get_closest_mode(int *w, int *h) { SDL_DisplayMode wantedmode, closestmode; wantedmode.w = *w; wantedmode.h = *h; wantedmode.format = 0; /* don't care for rest. */ wantedmode.refresh_rate = 0; wantedmode.driverdata = 0; if (SDL_GetClosestDisplayMode(window?SDL_GetWindowDisplayIndex(window):0, &wantedmode, &closestmode) == &closestmode) { *w=closestmode.w; *h=closestmode.h; } }
bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype) { if (!window) return false; if (graphics.get() && graphics->isCanvasActive()) throw love::Exception("love.window.setFullscreen cannot be called while a Canvas is active in love.graphics."); WindowSettings newsettings = settings; newsettings.fullscreen = fullscreen; newsettings.fstype = fstype; Uint32 sdlflags = 0; if (fullscreen) { if (fstype == FULLSCREEN_DESKTOP) sdlflags = SDL_WINDOW_FULLSCREEN_DESKTOP; else { sdlflags = SDL_WINDOW_FULLSCREEN; SDL_DisplayMode mode = {}; mode.w = windowWidth; mode.h = windowHeight; SDL_GetClosestDisplayMode(SDL_GetWindowDisplayIndex(window), &mode, &mode); SDL_SetWindowDisplayMode(window, &mode); } } #ifdef LOVE_ANDROID love::android::setImmersive(fullscreen); #endif if (SDL_SetWindowFullscreen(window, sdlflags) == 0) { SDL_GL_MakeCurrent(window, context); updateSettings(newsettings, true); // Apparently this gets un-set when we exit fullscreen (at least in OS X). if (!fullscreen) SDL_SetWindowMinimumSize(window, settings.minwidth, settings.minheight); return true; } return false; }
static int lua_SDL_GetClosestDisplayMode(lutok::state& state){ Lua_SDL_DisplayMode & dm = LOBJECT_INSTANCE(Lua_SDL_DisplayMode); SDL_DisplayMode * mode = new SDL_DisplayMode; if (SDL_GetClosestDisplayMode( state.to_integer(1), dm.check(2), mode) == 0){ dm.push(mode); return 1; }else{ delete mode; return 0; } }
Size Display::find_closest_fullscreen_video_mode(const Size& size) { SDL_DisplayMode target; SDL_DisplayMode closest; target.w = size.width; target.h = size.height; target.format = 0; // don't care target.refresh_rate = 0; // don't care target.driverdata = nullptr; if (!SDL_GetClosestDisplayMode(0, &target, &closest)) { log_error("couldn't find video mode matching %1%x%1%", size.width, size.height); return size; } else { return {closest.w, closest.h}; } }
qboolean VID_CreateWindow( int width, int height, qboolean fullscreen ) { #ifdef XASH_SDL static string wndname; Uint32 wndFlags = SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; Q_strncpy( wndname, GI->title, sizeof( wndname )); host.hWnd = SDL_CreateWindow(wndname, r_xpos->integer, r_ypos->integer, width, height, wndFlags); if( !host.hWnd ) { MsgDev( D_ERROR, "VID_CreateWindow: couldn't create '%s': %s\n", wndname, SDL_GetError()); return false; } if( fullscreen ) { SDL_DisplayMode want, got; want.w = width; want.h = height; want.driverdata = NULL; want.format = want.refresh_rate = 0; // don't care if( !SDL_GetClosestDisplayMode(0, &want, &got) ) return false; MsgDev(D_NOTE, "Got closest display mode: %ix%i@%i\n", got.w, got.h, got.refresh_rate); if( SDL_SetWindowDisplayMode(host.hWnd, &got) == -1 ) return false; if( SDL_SetWindowFullscreen(host.hWnd, SDL_WINDOW_FULLSCREEN) == -1 ) return false; } host.window_center_x = width / 2; host.window_center_y = height / 2; #if defined(_WIN32) { HICON ico; SDL_SysWMinfo info; if( FS_FileExists( GI->iconpath, true ) ) { char localPath[MAX_PATH]; Q_snprintf( localPath, sizeof( localPath ), "%s/%s", GI->gamedir, GI->iconpath ); ico = LoadImage( NULL, localPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE|LR_DEFAULTSIZE ); if( !ico ) { MsgDev( D_INFO, "Extract %s from pak if you want to see it.\n", GI->iconpath ); ico = LoadIcon( host.hInst, MAKEINTRESOURCE( 101 ) ); } } else ico = LoadIcon( host.hInst, MAKEINTRESOURCE( 101 ) ); if( SDL_GetWindowWMInfo( host.hWnd, &info ) ) { // info.info.info.info.info... Holy shit, SDL? SetClassLong( info.info.win.window, GCL_HICON, ico ); } } #endif SDL_ShowWindow( host.hWnd ); #else host.hWnd = 1; //fake window host.window_center_x = width / 2; host.window_center_y = height / 2; #endif if( !glw_state.initialized ) { if( !GL_CreateContext( )) return false; VID_StartupGamma(); } else { if( !GL_UpdateContext( )) return false; } return true; }
rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen ) { #ifdef XASH_SDL SDL_DisplayMode displayMode; SDL_GetCurrentDisplayMode(0, &displayMode); R_SaveVideoMode( width, height ); // check our desktop attributes glw_state.desktopBitsPixel = SDL_BITSPERPIXEL(displayMode.format); glw_state.desktopWidth = displayMode.w; glw_state.desktopHeight = displayMode.h; glState.fullScreen = fullscreen; // check for 4:3 or 5:4 if( width * 3 != height * 4 && width * 4 != height * 5 ) glState.wideScreen = true; else glState.wideScreen = false; if(!host.hWnd) { if( !VID_CreateWindow( width, height, fullscreen ) ) return rserr_invalid_mode; } else if( fullscreen ) { SDL_DisplayMode want, got; want.w = width; want.h = height; want.driverdata = NULL; want.format = want.refresh_rate = 0; // don't care if( !SDL_GetClosestDisplayMode(0, &want, &got) ) return rserr_invalid_mode; MsgDev(D_NOTE, "Got closest display mode: %ix%i@%i\n", got.w, got.h, got.refresh_rate); if( ( SDL_GetWindowFlags(host.hWnd) & SDL_WINDOW_FULLSCREEN ) == SDL_WINDOW_FULLSCREEN) if( SDL_SetWindowFullscreen(host.hWnd, 0) == -1 ) return rserr_invalid_fullscreen; if( SDL_SetWindowDisplayMode(host.hWnd, &got) ) return rserr_invalid_mode; if( SDL_SetWindowFullscreen(host.hWnd, SDL_WINDOW_FULLSCREEN) == -1 ) return rserr_invalid_fullscreen; R_ChangeDisplaySettingsFast( got.w, got.h ); } else { if( SDL_SetWindowFullscreen(host.hWnd, 0) ) return rserr_invalid_fullscreen; SDL_SetWindowSize(host.hWnd, width, height); R_ChangeDisplaySettingsFast( width, height ); } #endif // XASH_SDL return rserr_ok; }
static HRESULT WINAPI DRI3Present_SetPresentParameters( struct DRI3Present *This, D3DPRESENT_PARAMETERS *pPresentationParameters, D3DDISPLAYMODEEX *pFullscreenDisplayMode ) { if (!pPresentationParameters) { WARN("pPresentationParameters is NULL.\n"); return D3DERR_INVALIDCALL; } if (pPresentationParameters->Windowed) { SDL_SetWindowFullscreen(This->sdl_win, FALSE); DRI3Present_ChangePresentParameters(This, pPresentationParameters, FALSE); } else { if (!pFullscreenDisplayMode) { WARN("pFullscreenDisplayMode is NULL.\n"); return D3DERR_INVALIDCALL; } SDL_DisplayMode target; SDL_DisplayMode closest; memset(&target, 0, sizeof(target)); memset(&closest, 0, sizeof(closest)); // msdn: "When switching to full-screen mode, // Direct3D will try to find a desktop format that matches the back buffer format, // so that back buffer and front buffer formats will be identical (to eliminate the need for color conversion)." Uint32 preferred_format_for_backbuffer = ConvertToSDL(pPresentationParameters->BackBufferFormat); target.w = pFullscreenDisplayMode->Height; target.h = pFullscreenDisplayMode->Width; target.refresh_rate = pFullscreenDisplayMode->RefreshRate; if (preferred_format_for_backbuffer != SDL_PIXELFORMAT_UNKNOWN) target.format = preferred_format_for_backbuffer; else target.format = ConvertToSDL(pFullscreenDisplayMode->Format); SDL_DisplayMode* mode = NULL; if (FALSE) { /* * this doesn't seem to be a good idea: * it returns different mode even when the request mode exits and works... */ int Adapter = 0; mode = SDL_GetClosestDisplayMode(Adapter, &target, &closest); if (!mode) { WARN("Could not find requested fullscreen display mode (%dx%d %dHz, format = %d).\n", pFullscreenDisplayMode->Width, pFullscreenDisplayMode->Height, pFullscreenDisplayMode->RefreshRate, pFullscreenDisplayMode->Format); } } else { mode = ⌖ } int err = SDL_SetWindowDisplayMode(This->sdl_win, mode); if (err < 0) { WARN("SDL_SetWindowDisplayMode returned an error: %s\n", SDL_GetError()); return D3DERR_INVALIDCALL; } err = SDL_SetWindowFullscreen(This->sdl_win, SDL_WINDOW_FULLSCREEN); if (err < 0) { WARN("SDL_SetWindowFullscreen returned an error: %s\n", SDL_GetError()); return D3DERR_INVALIDCALL; } DRI3Present_ChangePresentParameters(This, pPresentationParameters, FALSE); } return D3D_OK; }
qboolean VID_CreateWindow( int width, int height, qboolean fullscreen ) { #ifdef XASH_SDL static string wndname; Uint32 wndFlags = SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; Q_strncpy( wndname, GI->title, sizeof( wndname )); host.hWnd = SDL_CreateWindow(wndname, r_xpos->integer, r_ypos->integer, width, height, wndFlags); if( !host.hWnd ) { MsgDev( D_ERROR, "VID_CreateWindow: couldn't create '%s': %s\n", wndname, SDL_GetError()); // remove MSAA, if it present, because // window creating may fail on GLX visual choose if( gl_msaa->integer ) { Cvar_Set("gl_msaa", "0"); GL_SetupAttributes(); // re-choose attributes // try again return VID_CreateWindow( width, height, fullscreen ); } return false; } if( fullscreen ) { SDL_DisplayMode want, got; want.w = width; want.h = height; want.driverdata = NULL; want.format = want.refresh_rate = 0; // don't care if( !SDL_GetClosestDisplayMode(0, &want, &got) ) return false; MsgDev(D_NOTE, "Got closest display mode: %ix%i@%i\n", got.w, got.h, got.refresh_rate); if( SDL_SetWindowDisplayMode(host.hWnd, &got) == -1 ) return false; if( SDL_SetWindowFullscreen(host.hWnd, SDL_WINDOW_FULLSCREEN) == -1 ) return false; } host.window_center_x = width / 2; host.window_center_y = height / 2; SDL_ShowWindow( host.hWnd ); #else host.hWnd = 1; //fake window host.window_center_x = width / 2; host.window_center_y = height / 2; #endif if( !glw_state.initialized ) { if( !GL_CreateContext( ) ) { return false; } VID_StartupGamma(); } else { if( !GL_UpdateContext( )) return false; } return true; }
bool Window::setWindow(int width, int height, WindowSettings *settings) { if (!graphics.get()) graphics.set(Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS)); if (graphics.get() && graphics->isCanvasActive()) throw love::Exception("love.window.setMode cannot be called while a Canvas is active in love.graphics."); WindowSettings f; if (settings) f = *settings; f.minwidth = std::max(f.minwidth, 1); f.minheight = std::max(f.minheight, 1); f.display = std::min(std::max(f.display, 0), getDisplayCount() - 1); // Use the desktop resolution if a width or height of 0 is specified. if (width == 0 || height == 0) { SDL_DisplayMode mode = {}; SDL_GetDesktopDisplayMode(f.display, &mode); width = mode.w; height = mode.h; } Uint32 sdlflags = SDL_WINDOW_OPENGL; // On Android we always must have fullscreen type FULLSCREEN_TYPE_DESKTOP #ifdef LOVE_ANDROID f.fstype = FULLSCREEN_DESKTOP; #endif if (f.fullscreen) { if (f.fstype == FULLSCREEN_DESKTOP) sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP; else { sdlflags |= SDL_WINDOW_FULLSCREEN; SDL_DisplayMode mode = {0, width, height, 0, nullptr}; // Fullscreen window creation will bug out if no mode can be used. if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == nullptr) { // GetClosestDisplayMode will fail if we request a size larger // than the largest available display mode, so we'll try to use // the largest (first) mode in that case. if (SDL_GetDisplayMode(f.display, 0, &mode) < 0) return false; } width = mode.w; height = mode.h; } } if (f.resizable) sdlflags |= SDL_WINDOW_RESIZABLE; if (f.borderless) sdlflags |= SDL_WINDOW_BORDERLESS; if (f.highdpi) sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI; int x = f.x; int y = f.y; if (f.useposition && !f.fullscreen) { // The position needs to be in the global coordinate space. SDL_Rect displaybounds = {}; SDL_GetDisplayBounds(f.display, &displaybounds); x += displaybounds.x; y += displaybounds.y; } else { if (f.centered) x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display); else x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display); } close(); if (!createWindowAndContext(x, y, width, height, sdlflags, f.msaa, f.stencil, f.depth)) return false; // Make sure the window keeps any previously set icon. setIcon(icon.get()); // Make sure the mouse keeps its previous grab setting. setMouseGrab(mouseGrabbed); // Enforce minimum window dimensions. SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight); if ((f.useposition || f.centered) && !f.fullscreen) SDL_SetWindowPosition(window, x, y); SDL_RaiseWindow(window); SDL_GL_SetSwapInterval(f.vsync); // Check if adaptive vsync was requested but not supported, and fall back // to regular vsync if so. if (f.vsync == -1 && SDL_GL_GetSwapInterval() != -1) SDL_GL_SetSwapInterval(1); updateSettings(f, false); if (graphics.get()) { double scaledw, scaledh; fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh); graphics->setMode((int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil); } #ifdef LOVE_ANDROID love::android::setImmersive(f.fullscreen); #endif return true; }