2022-04-19 17:49:43 +02:00
|
|
|
// Copyright 2002-2006 Marcus Geelnard
|
|
|
|
// Copyright 2006-2019 Camilla Löwy
|
|
|
|
// Copyright 2022 The Ebiten Authors
|
|
|
|
//
|
|
|
|
// This software is provided 'as-is', without any express or implied
|
|
|
|
// warranty. In no event will the authors be held liable for any damages
|
|
|
|
// arising from the use of this software.
|
|
|
|
//
|
|
|
|
// Permission is granted to anyone to use this software for any purpose,
|
|
|
|
// including commercial applications, and to alter it and redistribute it
|
|
|
|
// freely, subject to the following restrictions:
|
|
|
|
//
|
|
|
|
// 1. The origin of this software must not be misrepresented; you must not
|
|
|
|
// claim that you wrote the original software. If you use this software
|
|
|
|
// in a product, an acknowledgment in the product documentation would
|
|
|
|
// be appreciated but is not required.
|
|
|
|
//
|
|
|
|
// 2. Altered source versions must be plainly marked as such, and must not
|
|
|
|
// be misrepresented as being the original software.
|
|
|
|
//
|
|
|
|
// 3. This notice may not be removed or altered from any source
|
|
|
|
// distribution.
|
|
|
|
|
|
|
|
package glfwwin
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"math"
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (w *Window) inputWindowFocus(focused bool) {
|
|
|
|
if w.callbacks.focus != nil {
|
|
|
|
w.callbacks.focus(w, focused)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !focused {
|
|
|
|
for key := Key(0); key <= KeyLast; key++ {
|
|
|
|
if w.keys[key] == Press {
|
|
|
|
scancode := platformGetKeyScancode(key)
|
|
|
|
w.inputKey(key, scancode, Release, 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for button := MouseButton(0); button <= MouseButtonLast; button++ {
|
|
|
|
if w.mouseButtons[button] == Press {
|
|
|
|
w.inputMouseClick(button, Release, 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) inputWindowPos(x, y int) {
|
|
|
|
if w.callbacks.pos != nil {
|
|
|
|
w.callbacks.pos(w, x, y)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) inputWindowSize(width, height int) {
|
|
|
|
if w.callbacks.size != nil {
|
|
|
|
w.callbacks.size(w, width, height)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) inputWindowIconify(iconified bool) {
|
|
|
|
if w.callbacks.iconify != nil {
|
|
|
|
w.callbacks.iconify(w, iconified)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) inputWindowMaximize(maximized bool) {
|
|
|
|
if w.callbacks.maximize != nil {
|
|
|
|
w.callbacks.maximize(w, maximized)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) inputFramebufferSize(width, height int) {
|
|
|
|
if w.callbacks.fbsize != nil {
|
|
|
|
w.callbacks.fbsize(w, width, height)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) inputWindowContentScale(xscale, yscale float32) {
|
|
|
|
if w.callbacks.scale != nil {
|
|
|
|
w.callbacks.scale(w, xscale, yscale)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) inputWindowDamage() {
|
|
|
|
if w.callbacks.refresh != nil {
|
|
|
|
w.callbacks.refresh(w)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) inputWindowCloseRequest() {
|
|
|
|
w.shouldClose = true
|
|
|
|
|
|
|
|
if w.callbacks.close != nil {
|
|
|
|
w.callbacks.close(w)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) inputWindowMonitor(monitor *Monitor) {
|
|
|
|
w.monitor = monitor
|
|
|
|
}
|
|
|
|
|
|
|
|
func CreateWindow(width, height int, title string, monitor *Monitor, share *Window) (window *Window, ferr error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
if width <= 0 || height <= 0 {
|
|
|
|
return nil, fmt.Errorf("glfwwin: invalid window size %dx%d: %w", width, height, InvalidValue)
|
|
|
|
}
|
|
|
|
|
|
|
|
fbconfig := _glfw.hints.framebuffer
|
|
|
|
ctxconfig := _glfw.hints.context
|
|
|
|
wndconfig := _glfw.hints.window
|
|
|
|
|
|
|
|
wndconfig.width = width
|
|
|
|
wndconfig.height = height
|
|
|
|
wndconfig.title = title
|
|
|
|
ctxconfig.share = share
|
|
|
|
|
|
|
|
if err := checkValidContextConfig(&ctxconfig); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
window = &Window{
|
|
|
|
videoMode: VidMode{
|
|
|
|
Width: width,
|
|
|
|
Height: height,
|
|
|
|
RedBits: fbconfig.redBits,
|
|
|
|
GreenBits: fbconfig.greenBits,
|
|
|
|
BlueBits: fbconfig.blueBits,
|
|
|
|
RefreshRate: _glfw.hints.refreshRate,
|
|
|
|
},
|
|
|
|
|
|
|
|
monitor: monitor,
|
|
|
|
resizable: wndconfig.resizable,
|
|
|
|
decorated: wndconfig.decorated,
|
|
|
|
autoIconify: wndconfig.autoIconify,
|
|
|
|
floating: wndconfig.floating,
|
|
|
|
focusOnShow: wndconfig.focusOnShow,
|
|
|
|
cursorMode: CursorNormal,
|
|
|
|
|
|
|
|
doublebuffer: fbconfig.doublebuffer,
|
|
|
|
|
|
|
|
minwidth: DontCare,
|
|
|
|
minheight: DontCare,
|
|
|
|
maxwidth: DontCare,
|
|
|
|
maxheight: DontCare,
|
|
|
|
numer: DontCare,
|
|
|
|
denom: DontCare,
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
if ferr != nil {
|
|
|
|
window.Destroy()
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
// Open the actual window and create its context
|
|
|
|
if err := window.platformCreateWindow(&wndconfig, &ctxconfig, &fbconfig); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if ctxconfig.client != NoAPI {
|
|
|
|
if err := window.refreshContextAttribs(&ctxconfig); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if window.monitor != nil {
|
|
|
|
if wndconfig.centerCursor {
|
|
|
|
if err := window.centerCursorInContentArea(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if wndconfig.visible {
|
|
|
|
window.platformShowWindow()
|
|
|
|
if wndconfig.focused {
|
|
|
|
if err := window.platformFocusWindow(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return window, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func defaultWindowHints() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
// The default is OpenGL with minimum version 1.0
|
|
|
|
_glfw.hints.context = ctxconfig{
|
|
|
|
client: OpenGLAPI,
|
|
|
|
source: NativeContextAPI,
|
|
|
|
major: 1,
|
|
|
|
minor: 0,
|
|
|
|
}
|
|
|
|
|
|
|
|
// The default is a focused, visible, resizable window with decorations
|
|
|
|
_glfw.hints.window = wndconfig{
|
|
|
|
resizable: true,
|
|
|
|
visible: true,
|
|
|
|
decorated: true,
|
|
|
|
focused: true,
|
|
|
|
autoIconify: true,
|
|
|
|
centerCursor: true,
|
|
|
|
focusOnShow: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
|
|
|
|
// double buffered
|
|
|
|
_glfw.hints.framebuffer = fbconfig{
|
|
|
|
redBits: 8,
|
|
|
|
greenBits: 8,
|
|
|
|
blueBits: 8,
|
|
|
|
alphaBits: 8,
|
|
|
|
depthBits: 24,
|
|
|
|
stencilBits: 8,
|
|
|
|
doublebuffer: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
// The default is to select the highest available refresh rate
|
|
|
|
_glfw.hints.refreshRate = DontCare
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func WindowHint(hint Hint, value int) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
switch hint {
|
|
|
|
case RedBits:
|
|
|
|
_glfw.hints.framebuffer.redBits = value
|
|
|
|
case GreenBits:
|
|
|
|
_glfw.hints.framebuffer.greenBits = value
|
|
|
|
case BlueBits:
|
|
|
|
_glfw.hints.framebuffer.blueBits = value
|
|
|
|
case AlphaBits:
|
|
|
|
_glfw.hints.framebuffer.alphaBits = value
|
|
|
|
case DepthBits:
|
|
|
|
_glfw.hints.framebuffer.depthBits = value
|
|
|
|
case StencilBits:
|
|
|
|
_glfw.hints.framebuffer.stencilBits = value
|
|
|
|
case AccumRedBits:
|
|
|
|
_glfw.hints.framebuffer.accumRedBits = value
|
|
|
|
case AccumGreenBits:
|
|
|
|
_glfw.hints.framebuffer.accumGreenBits = value
|
|
|
|
case AccumBlueBits:
|
|
|
|
_glfw.hints.framebuffer.accumBlueBits = value
|
|
|
|
case AccumAlphaBits:
|
|
|
|
_glfw.hints.framebuffer.accumAlphaBits = value
|
|
|
|
case AuxBuffers:
|
|
|
|
_glfw.hints.framebuffer.auxBuffers = value
|
|
|
|
case Stereo:
|
|
|
|
_glfw.hints.framebuffer.stereo = intToBool(value)
|
|
|
|
case DoubleBuffer:
|
|
|
|
_glfw.hints.framebuffer.doublebuffer = intToBool(value)
|
|
|
|
case TransparentFramebuffer:
|
|
|
|
_glfw.hints.framebuffer.transparent = intToBool(value)
|
|
|
|
case Samples:
|
|
|
|
_glfw.hints.framebuffer.samples = value
|
|
|
|
case SRGBCapable:
|
|
|
|
_glfw.hints.framebuffer.sRGB = intToBool(value)
|
|
|
|
case Resizable:
|
|
|
|
_glfw.hints.window.resizable = intToBool(value)
|
|
|
|
case Decorated:
|
|
|
|
_glfw.hints.window.decorated = intToBool(value)
|
|
|
|
case Focused:
|
|
|
|
_glfw.hints.window.focused = intToBool(value)
|
|
|
|
case AutoIconify:
|
|
|
|
_glfw.hints.window.autoIconify = intToBool(value)
|
|
|
|
case Floating:
|
|
|
|
_glfw.hints.window.floating = intToBool(value)
|
|
|
|
case Maximized:
|
|
|
|
_glfw.hints.window.maximized = intToBool(value)
|
|
|
|
case Visible:
|
|
|
|
_glfw.hints.window.visible = intToBool(value)
|
|
|
|
case ScaleToMonitor:
|
|
|
|
_glfw.hints.window.scaleToMonitor = intToBool(value)
|
|
|
|
case CenterCursor:
|
|
|
|
_glfw.hints.window.centerCursor = intToBool(value)
|
|
|
|
case FocusOnShow:
|
|
|
|
_glfw.hints.window.focusOnShow = intToBool(value)
|
|
|
|
case ClientAPI:
|
|
|
|
_glfw.hints.context.client = value
|
|
|
|
case ContextCreationAPI:
|
|
|
|
_glfw.hints.context.source = value
|
|
|
|
case ContextVersionMajor:
|
|
|
|
_glfw.hints.context.major = value
|
|
|
|
case ContextVersionMinor:
|
|
|
|
_glfw.hints.context.minor = value
|
|
|
|
case ContextRobustness:
|
|
|
|
_glfw.hints.context.robustness = value
|
|
|
|
case OpenGLForwardCompat:
|
|
|
|
_glfw.hints.context.forward = intToBool(value)
|
|
|
|
case OpenGLDebugContext:
|
|
|
|
_glfw.hints.context.debug = intToBool(value)
|
|
|
|
case ContextNoError:
|
|
|
|
_glfw.hints.context.noerror = intToBool(value)
|
|
|
|
case OpenGLProfile:
|
|
|
|
_glfw.hints.context.profile = value
|
|
|
|
case ContextReleaseBehavior:
|
|
|
|
_glfw.hints.context.release = value
|
|
|
|
case RefreshRate:
|
|
|
|
_glfw.hints.refreshRate = value
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("glfwwin: invalid window hint 0x%08X: %w", hint, InvalidEnum)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-05-27 13:15:36 +02:00
|
|
|
// WindowHintString is not implemented.
|
2022-04-19 17:49:43 +02:00
|
|
|
|
|
|
|
func (w *Window) Destroy() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
// Allow closing of NULL (to match the behavior of free)
|
|
|
|
if w == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear all callbacks to avoid exposing a half torn-down w object
|
|
|
|
//memset(&w.callbacks, 0, sizeof(w.callbacks))
|
|
|
|
|
|
|
|
// The w's context must not be current on another thread when the
|
|
|
|
// w is destroyed
|
|
|
|
current, err := _glfw.contextSlot.get()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if uintptr(unsafe.Pointer(w)) == current {
|
|
|
|
if err := (*Window)(nil).MakeContextCurrent(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
w.platformDestroyWindow()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) ShouldClose() (bool, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return false, NotInitialized
|
|
|
|
}
|
|
|
|
return w.shouldClose, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetShouldClose(value bool) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
w.shouldClose = value
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetTitle(title string) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
if err := w.platformSetWindowTitle(title); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetIcon(images []*Image) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
if err := w.platformSetWindowIcon(images); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) GetPos() (xpos, ypos int, err error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return 0, 0, NotInitialized
|
|
|
|
}
|
|
|
|
return w.platformGetWindowPos()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetPos(xpos, ypos int) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
if w.monitor != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if err := w.platformSetWindowPos(xpos, ypos); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) GetSize() (width, height int, err error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return 0, 0, NotInitialized
|
|
|
|
}
|
|
|
|
return w.platformGetWindowSize()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetSize(width, height int) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
w.videoMode.Width = width
|
|
|
|
w.videoMode.Height = height
|
|
|
|
if err := w.platformSetWindowSize(width, height); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetSizeLimits(minwidth, minheight, maxwidth, maxheight int) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
if minwidth != DontCare && minheight != DontCare {
|
|
|
|
if minwidth < 0 || minheight < 0 {
|
|
|
|
return fmt.Errorf("glfwwin: invalid window minimum size %dx%d: %w", minwidth, minheight, InvalidValue)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if maxwidth != DontCare && maxheight != DontCare {
|
|
|
|
if maxwidth < 0 || maxheight < 0 || maxwidth < minwidth || maxheight < minheight {
|
|
|
|
return fmt.Errorf("glfwwin: invalid window maximum size %dx%d: %w", maxwidth, maxheight, InvalidValue)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
w.minwidth = minwidth
|
|
|
|
w.minheight = minheight
|
|
|
|
w.maxwidth = maxwidth
|
|
|
|
w.maxheight = maxheight
|
|
|
|
|
|
|
|
if w.monitor != nil || !w.resizable {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := w.platformSetWindowSizeLimits(minwidth, minheight, maxwidth, maxheight); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetAspectRatio(numer, denom int) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
if numer != DontCare && denom != DontCare {
|
|
|
|
if numer <= 0 || denom <= 0 {
|
|
|
|
return fmt.Errorf("glfwwin: invalid window aspect ratio %d:%d: %w", numer, denom, InvalidValue)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
w.numer = numer
|
|
|
|
w.denom = denom
|
|
|
|
|
|
|
|
if w.monitor != nil || !w.resizable {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := w.platformSetWindowAspectRatio(numer, denom); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) GetFramebufferSize() (width, height int, err error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return 0, 0, NotInitialized
|
|
|
|
}
|
|
|
|
return w.platformGetFramebufferSize()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) GetFrameSize() (left, top, right, bottom int, err error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return 0, 0, 0, 0, NotInitialized
|
|
|
|
}
|
|
|
|
return w.platformGetWindowFrameSize()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) GetContentScale() (xscale, yscale float32, err error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return 0, 0, NotInitialized
|
|
|
|
}
|
|
|
|
return w.platformGetWindowContentScale()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) GetOpacity() (float32, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return 0, NotInitialized
|
|
|
|
}
|
|
|
|
return w.platformGetWindowOpacity()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetOpacity(opacity float32) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
if opacity != opacity || opacity < 0 || opacity > 1 {
|
|
|
|
return fmt.Errorf("glfwwin: invalid window opacity %f: %w", opacity, InvalidValue)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := w.platformSetWindowOpacity(opacity); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) Iconify() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
w.platformIconifyWindow()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) Restore() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
w.platformRestoreWindow()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) Maximize() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
if w.monitor != nil {
|
|
|
|
return nil
|
|
|
|
}
|
2022-05-20 16:09:10 +02:00
|
|
|
if err := w.platformMaximizeWindow(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-04-19 17:49:43 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) Show() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
if w.monitor != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
w.platformShowWindow()
|
|
|
|
|
|
|
|
if w.focusOnShow {
|
|
|
|
if err := w.platformFocusWindow(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) RequestAttention() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
w.platformRequestWindowAttention()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) Hide() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
if w.monitor != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
w.platformHideWindow()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) Focus() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
if err := w.platformFocusWindow(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) GetAttrib(attrib Hint) (int, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return 0, NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
switch attrib {
|
|
|
|
case Focused:
|
|
|
|
return boolToInt(w.platformWindowFocused()), nil
|
|
|
|
case Iconified:
|
|
|
|
return boolToInt(w.platformWindowIconified()), nil
|
|
|
|
case Visible:
|
|
|
|
return boolToInt(w.platformWindowVisible()), nil
|
|
|
|
case Maximized:
|
|
|
|
return boolToInt(w.platformWindowMaximized()), nil
|
|
|
|
case Hovered:
|
|
|
|
b, err := w.platformWindowHovered()
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return boolToInt(b), nil
|
|
|
|
case FocusOnShow:
|
|
|
|
return boolToInt(w.focusOnShow), nil
|
|
|
|
case TransparentFramebuffer:
|
|
|
|
return boolToInt(w.platformFramebufferTransparent()), nil
|
|
|
|
case Resizable:
|
|
|
|
return boolToInt(w.resizable), nil
|
|
|
|
case Decorated:
|
|
|
|
return boolToInt(w.decorated), nil
|
|
|
|
case Floating:
|
|
|
|
return boolToInt(w.floating), nil
|
|
|
|
case AutoIconify:
|
|
|
|
return boolToInt(w.autoIconify), nil
|
|
|
|
case ClientAPI:
|
|
|
|
return w.context.client, nil
|
|
|
|
case ContextCreationAPI:
|
|
|
|
return w.context.source, nil
|
|
|
|
case ContextVersionMajor:
|
|
|
|
return w.context.major, nil
|
|
|
|
case ContextVersionMinor:
|
|
|
|
return w.context.minor, nil
|
|
|
|
case ContextRevision:
|
|
|
|
return w.context.revision, nil
|
|
|
|
case ContextRobustness:
|
|
|
|
return w.context.robustness, nil
|
|
|
|
case OpenGLForwardCompat:
|
|
|
|
return boolToInt(w.context.forward), nil
|
|
|
|
case OpenGLDebugContext:
|
|
|
|
return boolToInt(w.context.debug), nil
|
|
|
|
case OpenGLProfile:
|
|
|
|
return w.context.profile, nil
|
|
|
|
case ContextReleaseBehavior:
|
|
|
|
return w.context.release, nil
|
|
|
|
case ContextNoError:
|
|
|
|
return boolToInt(w.context.noerror), nil
|
|
|
|
default:
|
|
|
|
return 0, fmt.Errorf("glfwwin: invalid window attribute 0x%08X: %w", attrib, InvalidEnum)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetAttrib(attrib Hint, value int) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
bValue := intToBool(value)
|
|
|
|
|
|
|
|
switch attrib {
|
|
|
|
case AutoIconify:
|
|
|
|
w.autoIconify = bValue
|
|
|
|
return nil
|
|
|
|
case Resizable:
|
|
|
|
if w.resizable == bValue {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
w.resizable = bValue
|
|
|
|
if w.monitor == nil {
|
|
|
|
if err := w.platformSetWindowResizable(bValue); err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
case Decorated:
|
|
|
|
if w.decorated == bValue {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
w.decorated = bValue
|
|
|
|
if w.monitor == nil {
|
|
|
|
if err := w.platformSetWindowDecorated(bValue); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
case Floating:
|
|
|
|
if w.floating == bValue {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
w.floating = bValue
|
|
|
|
if w.monitor == nil {
|
|
|
|
if err := w.platformSetWindowFloating(bValue); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
case FocusOnShow:
|
|
|
|
w.focusOnShow = bValue
|
|
|
|
return nil
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("glfwwin: invalid window attribute 0x%08X: %w", attrib, InvalidEnum)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) GetMonitor() (*Monitor, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
return w.monitor, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetMonitor(monitor *Monitor, xpos, ypos, width, height, refreshRate int) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
|
|
|
|
if width <= 0 || height <= 0 {
|
|
|
|
return fmt.Errorf("glfwwin: invalid window size %dx%d: %w", width, height, InvalidValue)
|
|
|
|
}
|
|
|
|
|
|
|
|
if refreshRate < 0 && refreshRate != DontCare {
|
|
|
|
return fmt.Errorf("glfwwin: invalid refresh rate %d: %w", refreshRate, InvalidValue)
|
|
|
|
}
|
|
|
|
|
|
|
|
w.videoMode.Width = width
|
|
|
|
w.videoMode.Height = height
|
|
|
|
w.videoMode.RefreshRate = refreshRate
|
|
|
|
|
|
|
|
if err := w.platformSetWindowMonitor(monitor, xpos, ypos, width, height, refreshRate); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetUserPointer(pointer unsafe.Pointer) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
w.userPointer = pointer
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) GetUserPointer() (unsafe.Pointer, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
return w.userPointer, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetPosCallback(cbfun PosCallback) (PosCallback, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
old := w.callbacks.pos
|
|
|
|
w.callbacks.pos = cbfun
|
|
|
|
return old, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetSizeCallback(cbfun SizeCallback) (SizeCallback, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
old := w.callbacks.size
|
|
|
|
w.callbacks.size = cbfun
|
|
|
|
return old, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetCloseCallback(cbfun CloseCallback) (CloseCallback, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
old := w.callbacks.close
|
|
|
|
w.callbacks.close = cbfun
|
|
|
|
return old, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetRefreshCallback(cbfun RefreshCallback) (RefreshCallback, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
old := w.callbacks.refresh
|
|
|
|
w.callbacks.refresh = cbfun
|
|
|
|
return old, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetFocusCallback(cbfun FocusCallback) (FocusCallback, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
old := w.callbacks.focus
|
|
|
|
w.callbacks.focus = cbfun
|
|
|
|
return old, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetIconifyCallback(cbfun IconifyCallback) (IconifyCallback, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
old := w.callbacks.iconify
|
|
|
|
w.callbacks.iconify = cbfun
|
|
|
|
return old, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetMaximizeCallback(cbfun MaximizeCallback) (MaximizeCallback, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
old := w.callbacks.maximize
|
|
|
|
w.callbacks.maximize = cbfun
|
|
|
|
return old, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetFramebufferSizeCallback(cbfun FramebufferSizeCallback) (FramebufferSizeCallback, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
old := w.callbacks.fbsize
|
|
|
|
w.callbacks.fbsize = cbfun
|
|
|
|
return old, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Window) SetContentScaleCallback(cbfun ContentScaleCallback) (ContentScaleCallback, error) {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return nil, NotInitialized
|
|
|
|
}
|
|
|
|
old := w.callbacks.scale
|
|
|
|
w.callbacks.scale = cbfun
|
|
|
|
return old, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func PollEvents() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
if err := platformPollEvents(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func WaitEvents() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
if err := platformWaitEvents(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func WaitEventsTimeout(timeout float64) error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
if timeout != timeout || timeout < 0.0 || timeout > math.MaxFloat64 {
|
|
|
|
return fmt.Errorf("glfwwin: invalid time %f: %w", timeout, InvalidValue)
|
|
|
|
}
|
|
|
|
if err := platformWaitEventsTimeout(timeout); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func PostEmptyEvent() error {
|
|
|
|
if !_glfw.initialized {
|
|
|
|
return NotInitialized
|
|
|
|
}
|
|
|
|
if err := platformPostEmptyEvent(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|