// GetDesktopDimensions gets the dimensions of a display for the given index func GetDesktopDimensions(displayindex int) (int32, int32) { var width, height int32 if displayindex >= 0 && displayindex < GetDisplayCount() { var mode sdl.DisplayMode sdl.GetDesktopDisplayMode(displayindex, &mode) width = mode.W height = mode.H } return width, height }
// NewWindow will create a new sdl window with a gl context. It will also destroy // an old one if there is one already. Errors returned come straight from SDL so // errors will be indicitive of SDL errors func NewWindow() (*window, error) { if current_window != nil || initError != nil { return current_window, initError } var config *windowConfig var err error if err = sdl.InitSubSystem(sdl.INIT_VIDEO); err != nil { panic(err) } if config, err = loadConfig(); err != nil { panic(err) } config.Minwidth = int32(math.Max(float64(config.Minwidth), 1.0)) config.Minheight = int32(math.Max(float64(config.Minheight), 1.0)) config.Display = int(math.Min(math.Max(float64(config.Display), 0.0), float64(GetDisplayCount()-1))) if config.Width == 0 || config.Height == 0 { var mode sdl.DisplayMode sdl.GetDesktopDisplayMode(config.Display, &mode) config.Width = mode.W config.Height = mode.H } sdlflags := uint32(sdl.WINDOW_OPENGL) if config.Fullscreen { if config.Fstype == "desktop" { sdlflags |= sdl.WINDOW_FULLSCREEN_DESKTOP } else { sdlflags |= sdl.WINDOW_FULLSCREEN mode := sdl.DisplayMode{W: int32(config.Width), H: int32(config.Height)} // Fullscreen window creation will bug out if no mode can be used. if _, err := sdl.GetClosestDisplayMode(config.Display, &mode, &mode); err != nil { // 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 err := sdl.GetDisplayMode(config.Display, 0, &mode); err != nil { return nil, err } } config.Width = mode.W config.Height = mode.H } } if config.Resizable { sdlflags |= sdl.WINDOW_RESIZABLE } if config.Borderless { sdlflags |= sdl.WINDOW_BORDERLESS } if config.Highdpi { sdlflags |= sdl.WINDOW_ALLOW_HIGHDPI } if config.Fullscreen { // The position needs to be in the global coordinate space. var displaybounds sdl.Rect sdl.GetDisplayBounds(config.Display, &displaybounds) config.X += displaybounds.X config.Y += displaybounds.Y } else { if config.Centered { config.X = sdl.WINDOWPOS_CENTERED config.Y = sdl.WINDOWPOS_CENTERED } else { config.X = sdl.WINDOWPOS_UNDEFINED config.Y = sdl.WINDOWPOS_UNDEFINED } } if current_window != nil { Destroy() } created = false new_window, err := createWindowAndContext(config, sdlflags) if err != nil { return nil, err } created = true if new_window.Config.Icon != "" { SetIcon(config.Icon) } SetMouseGrab(false) SetMinimumSize(config.Minwidth, config.Minheight) SetTitle(config.Title) if config.Centered && !config.Fullscreen { SetPosition(config.X, config.Y) } getCurrent().sdl_window.Raise() if config.Vsync { sdl.GL_SetSwapInterval(1) } else { sdl.GL_SetSwapInterval(0) } new_window.open = true return new_window, nil }
// win==nil requests a full-screen window func Run(win WindowSpec) int { // All SDL calls must come from same thread. runtime.LockOSThread() defer runtime.UnlockOSThread() err := sdl.Init(sdl.INIT_EVERYTHING) if err != nil { panic(err) } defer sdl.Quit() // Install audio callback spec := &sdl.AudioSpec{ Freq: SampleRate, Format: sdl.AUDIO_F32SYS, Channels: 1, Samples: 4096, Callback: sdl.AudioCallback(C.getSoundSamplesAdaptor), } audioDevice, err := sdl.OpenAudioDevice("", false, spec, nil, 0) if err != nil { fmt.Fprintf(os.Stderr, "Failed to open audio device: %v\n", err) panic(err) } if audioDevice < 2 { fmt.Fprintf(os.Stderr, "Audio device=%v < 2 contrary to SDL-2 documentation\n", audioDevice, err) } sdl.PauseAudioDevice(audioDevice, false) // Create window var window *sdl.Window if win != nil { // Partial screen winWidth, winHeight := win.Size() window, err = sdl.CreateWindow(win.Title(), sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, int(winWidth), int(winHeight), sdl.WINDOW_SHOWN) } else { // Full screen if isMacOS { // Contrary to https://wiki.libsdl.org/SDL_CreateWindow, on MacOS 10.11.1 // a call to sdl.CreateWindow in fullscreen mode *does* use the w and h parameters. // So ask what the display size is. var mode sdl.DisplayMode err = sdl.GetDesktopDisplayMode(0, &mode) if err != nil { fmt.Fprintf(os.Stderr, "Cannot get desktop display mode") panic(err) } window, err = sdl.CreateWindow("", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, int(mode.W), int(mode.H), sdl.WINDOW_SHOWN|sdl.WINDOW_FULLSCREEN_DESKTOP) } else { window, err = sdl.CreateWindow("", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, 0, 0, sdl.WINDOW_SHOWN|sdl.WINDOW_FULLSCREEN_DESKTOP) } } if err != nil { fmt.Fprintf(os.Stderr, "Failed to create window: %v\n", err) panic(err) } defer window.Destroy() // Create renderer width, height := window.GetSize() renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED|sdl.RENDERER_PRESENTVSYNC) if err != nil { fmt.Fprintf(os.Stderr, "Failed to create renderer: %v\n", err) panic(err) } defer renderer.Destroy() var nTex = 1 if isMacOS { // Work around MacOS bug via double buffering nTex = 2 } // Create texture tex := make([]*sdl.Texture, nTex) for i := range tex { tex[i], err = renderer.CreateTexture(sdl.PIXELFORMAT_ARGB8888, sdl.TEXTUREACCESS_STREAMING, width, height) if err != nil { fmt.Fprintf(os.Stderr, "renderer.CreateTexture: %v\n", err) panic(err) } defer tex[i].Destroy() } for _, r := range renderClientList { r.Init(int32(width), int32(height)) } // Loop until quit for i := 0; ; i ^= nTex - 1 { for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch e := event.(type) { case *sdl.QuitEvent: return 0 case *sdl.MouseMotionEvent: // Go equivalent of SDL_PRESSED seems to be missing, so compare with zero. if e.State != 0 { forwardMouseEvent(MouseDrag, int32(e.X), int32(e.Y)) } else { forwardMouseEvent(MouseMove, int32(e.X), int32(e.Y)) } case *sdl.MouseButtonEvent: switch e.Type { case sdl.MOUSEBUTTONDOWN: forwardMouseEvent(MouseDown, int32(e.X), int32(e.Y)) case sdl.MOUSEBUTTONUP: forwardMouseEvent(MouseUp, int32(e.X), int32(e.Y)) } case *sdl.KeyDownEvent: var k Key if 0x20 <= e.Keysym.Sym && e.Keysym.Sym < 0x7F { // Printable ASCII k = Key(e.Keysym.Sym) } else { // Try special character table k = keyMap[e.Keysym.Sym] } if k != 0 { forwardKeyEvent(k) } } } pixels, pitch := lockTexture(tex[i], width, height) pm := MakePixMap(int32(width), int32(height), pixels, int32(pitch)) for _, r := range renderClientList { r.Render(pm) } tex[i].Unlock() err := renderer.Clear() if err != nil { fmt.Fprintf(os.Stderr, "renderer.Clear: %v", err) panic(err) } renderer.Copy(tex[i], nil, nil) if err != nil { fmt.Fprintf(os.Stderr, "renderer.Copy: %v", err) panic(err) } renderer.Present() } }