From e7ad5c52feceeeda2ff17d1af86b51a39fcc234a Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Tue, 3 Oct 2023 23:07:53 +0900 Subject: [PATCH] internal/glfw: merge internal/goglfw into internal/glfw This also changes APIs in internal/glfw to return errors. Updates #2703 --- .github/workflows/govetblock_windows.txt | 2 +- internal/{goglfw => glfw}/api_windows.go | 170 ++-- ...callback_goglfw.go => callback_windows.go} | 53 +- internal/{goglfw => glfw}/context_windows.go | 48 +- internal/glfw/glfw3h_windows.go | 21 + internal/glfw/glfw_cglfw.go | 174 ++-- internal/glfw/glfw_goglfw.go | 416 -------- internal/{goglfw => glfw}/init_windows.go | 14 +- internal/{goglfw => glfw}/input_windows.go | 20 +- internal/{goglfw => glfw}/internal_windows.go | 2 +- internal/{goglfw => glfw}/monitor_windows.go | 2 +- internal/glfw/native_windows.go | 27 - internal/glfw/type_goglfw.go | 33 - .../wgl_context_windows.go} | 14 +- .../win32_init_windows.go} | 2 +- .../win32_monitor_windows.go} | 18 +- .../win32_platform_windows.go} | 2 +- .../win32_thread_windows.go} | 8 +- .../win32_window_windows.go} | 12 +- internal/{goglfw => glfw}/window_windows.go | 43 +- internal/goglfw/glfw3h_windows.go | 341 ------- .../graphicsdriver/opengl/graphics_glfw.go | 41 +- internal/ui/input_glfw.go | 50 +- internal/ui/monitor_glfw.go | 30 +- internal/ui/ui_glfw.go | 922 ++++++++++++++---- internal/ui/ui_glfw_darwin.go | 32 +- internal/ui/ui_glfw_linbsd.go | 38 +- internal/ui/ui_glfw_windows.go | 33 +- internal/ui/window_glfw.go | 128 ++- 29 files changed, 1296 insertions(+), 1400 deletions(-) rename internal/{goglfw => glfw}/api_windows.go (92%) rename internal/glfw/{callback_goglfw.go => callback_windows.go} (55%) rename internal/{goglfw => glfw}/context_windows.go (86%) create mode 100644 internal/glfw/glfw3h_windows.go delete mode 100644 internal/glfw/glfw_goglfw.go rename internal/{goglfw => glfw}/init_windows.go (78%) rename internal/{goglfw => glfw}/input_windows.go (93%) rename internal/{goglfw => glfw}/internal_windows.go (99%) rename internal/{goglfw => glfw}/monitor_windows.go (99%) delete mode 100644 internal/glfw/native_windows.go delete mode 100644 internal/glfw/type_goglfw.go rename internal/{goglfw/wglcontext_windows.go => glfw/wgl_context_windows.go} (96%) rename internal/{goglfw/win32init_windows.go => glfw/win32_init_windows.go} (99%) rename internal/{goglfw/win32monitor_windows.go => glfw/win32_monitor_windows.go} (93%) rename internal/{goglfw/win32platform_windows.go => glfw/win32_platform_windows.go} (99%) rename internal/{goglfw/win32thread_windows.go => glfw/win32_thread_windows.go} (85%) rename internal/{goglfw/win32window_windows.go => glfw/win32_window_windows.go} (99%) rename internal/{goglfw => glfw}/window_windows.go (93%) delete mode 100644 internal/goglfw/glfw3h_windows.go diff --git a/.github/workflows/govetblock_windows.txt b/.github/workflows/govetblock_windows.txt index 2cd38baf7..1473fa7e0 100644 --- a/.github/workflows/govetblock_windows.txt +++ b/.github/workflows/govetblock_windows.txt @@ -1,2 +1,2 @@ +github.com/hajimehoshi/ebiten/v2/internal/glfw github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/directx -github.com/hajimehoshi/ebiten/v2/internal/goglfw diff --git a/internal/goglfw/api_windows.go b/internal/glfw/api_windows.go similarity index 92% rename from internal/goglfw/api_windows.go rename to internal/glfw/api_windows.go index ed38e9f59..f114665bc 100644 --- a/internal/goglfw/api_windows.go +++ b/internal/glfw/api_windows.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package goglfw +package glfw import ( "errors" @@ -839,7 +839,7 @@ func _AdjustWindowRectEx(lpRect *_RECT, dwStyle uint32, menu bool, dwExStyle uin } r, _, e := procAdjustWindowRectEx.Call(uintptr(unsafe.Pointer(lpRect)), uintptr(dwStyle), bMenu, uintptr(dwExStyle)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: AdjustWindowRectEx failed: %w", e) + return fmt.Errorf("glfw: AdjustWindowRectEx failed: %w", e) } return nil } @@ -851,7 +851,7 @@ func _AdjustWindowRectExForDpi(lpRect *_RECT, dwStyle uint32, menu bool, dwExSty } r, _, e := procAdjustWindowRectExForDpi.Call(uintptr(unsafe.Pointer(lpRect)), uintptr(dwStyle), bMenu, uintptr(dwExStyle), uintptr(dpi)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: AdjustWindowRectExForDpi failed: %w", e) + return fmt.Errorf("glfw: AdjustWindowRectExForDpi failed: %w", e) } return nil } @@ -859,7 +859,7 @@ func _AdjustWindowRectExForDpi(lpRect *_RECT, dwStyle uint32, menu bool, dwExSty func _BringWindowToTop(hWnd windows.HWND) error { r, _, e := procBringWindowToTop.Call(uintptr(hWnd)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: BringWindowToTop failed: %w", e) + return fmt.Errorf("glfw: BringWindowToTop failed: %w", e) } return nil } @@ -870,7 +870,7 @@ func _ChangeDisplaySettingsExW(deviceName string, lpDevMode *_DEVMODEW, hwnd win var err error lpszDeviceName, err = windows.UTF16PtrFromString(deviceName) if err != nil { - panic("goglfw: device name must not include a NUL character") + panic("glfw: device name must not include a NUL character") } } @@ -884,7 +884,7 @@ func _ChangeDisplaySettingsExW(deviceName string, lpDevMode *_DEVMODEW, hwnd win func _ChangeWindowMessageFilterEx(hwnd windows.HWND, message uint32, action uint32, pChangeFilterStruct *_CHANGEFILTERSTRUCT) error { r, _, e := procChangeWindowMessageFilterEx.Call(uintptr(hwnd), uintptr(message), uintptr(action), uintptr(unsafe.Pointer(pChangeFilterStruct))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: ChangeWindowMessageFilterEx failed: %w", e) + return fmt.Errorf("glfw: ChangeWindowMessageFilterEx failed: %w", e) } return nil } @@ -892,7 +892,7 @@ func _ChangeWindowMessageFilterEx(hwnd windows.HWND, message uint32, action uint func _ChoosePixelFormat(hdc _HDC, ppfd *_PIXELFORMATDESCRIPTOR) (int32, error) { r, _, e := procChoosePixelFormat.Call(uintptr(hdc), uintptr(unsafe.Pointer(ppfd))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return 0, fmt.Errorf("goglfw: ChoosePixelFormat failed: %w", e) + return 0, fmt.Errorf("glfw: ChoosePixelFormat failed: %w", e) } return int32(r), nil } @@ -900,7 +900,7 @@ func _ChoosePixelFormat(hdc _HDC, ppfd *_PIXELFORMATDESCRIPTOR) (int32, error) { func _ClientToScreen(hWnd windows.HWND, lpPoint *_POINT) error { r, _, e := procClientToScreen.Call(uintptr(hWnd), uintptr(unsafe.Pointer(lpPoint))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: ClientToScreen failed: %w", e) + return fmt.Errorf("glfw: ClientToScreen failed: %w", e) } return nil } @@ -908,7 +908,7 @@ func _ClientToScreen(hWnd windows.HWND, lpPoint *_POINT) error { func _ClipCursor(lpRect *_RECT) error { r, _, e := procClipCursor.Call(uintptr(unsafe.Pointer(lpRect))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: ClipCursor failed: %w", e) + return fmt.Errorf("glfw: ClipCursor failed: %w", e) } return nil } @@ -916,7 +916,7 @@ func _ClipCursor(lpRect *_RECT) error { func _CreateBitmap(nWidth int32, nHeight int32, nPlanes uint32, nBitCount uint32, lpBits unsafe.Pointer) (_HBITMAP, error) { r, _, e := procCreateBitmap.Call(uintptr(nWidth), uintptr(nHeight), uintptr(nPlanes), uintptr(nBitCount), uintptr(lpBits)) if _HBITMAP(r) == 0 { - return 0, fmt.Errorf("goglfw: CreateBitmap failed: %w", e) + return 0, fmt.Errorf("glfw: CreateBitmap failed: %w", e) } return _HBITMAP(r), nil } @@ -926,7 +926,7 @@ func _CreateDIBSection(hdc _HDC, pbmi *_BITMAPV5HEADER, usage uint32, hSection w var bits *byte r, _, e := procCreateDIBSection.Call(uintptr(hdc), uintptr(unsafe.Pointer(pbmi)), uintptr(usage), uintptr(unsafe.Pointer(&bits)), uintptr(hSection), uintptr(offset)) if _HBITMAP(r) == 0 { - return 0, nil, fmt.Errorf("goglfw: CreateDIBSection failed: %w", e) + return 0, nil, fmt.Errorf("glfw: CreateDIBSection failed: %w", e) } return _HBITMAP(r), bits, nil } @@ -934,7 +934,7 @@ func _CreateDIBSection(hdc _HDC, pbmi *_BITMAPV5HEADER, usage uint32, hSection w func _CreateRectRgn(x1, y1, x2, y2 int32) (_HRGN, error) { r, _, e := procCreateRectRgn.Call(uintptr(x1), uintptr(y1), uintptr(x2), uintptr(y2)) if _HRGN(r) == 0 { - return 0, fmt.Errorf("goglfw: CreateRectRgn failed: %w", e) + return 0, fmt.Errorf("glfw: CreateRectRgn failed: %w", e) } return _HRGN(r), nil } @@ -942,7 +942,7 @@ func _CreateRectRgn(x1, y1, x2, y2 int32) (_HRGN, error) { func _CreateIconIndirect(piconinfo *_ICONINFO) (_HICON, error) { r, _, e := procCreateIconIndirect.Call(uintptr(unsafe.Pointer(piconinfo))) if _HICON(r) == 0 { - return 0, fmt.Errorf("goglfw: CreateIconIndirect failed: %w", e) + return 0, fmt.Errorf("glfw: CreateIconIndirect failed: %w", e) } return _HICON(r), nil } @@ -953,7 +953,7 @@ func _CreateWindowExW(dwExStyle uint32, className string, windowName string, dwS var err error lpClassName, err = windows.UTF16PtrFromString(className) if err != nil { - panic("goglfw: class name msut not include a NUL character") + panic("glfw: class name msut not include a NUL character") } } @@ -962,7 +962,7 @@ func _CreateWindowExW(dwExStyle uint32, className string, windowName string, dwS var err error lpWindowName, err = windows.UTF16PtrFromString(windowName) if err != nil { - panic("goglfw: window name msut not include a NUL character") + panic("glfw: window name msut not include a NUL character") } } @@ -974,7 +974,7 @@ func _CreateWindowExW(dwExStyle uint32, className string, windowName string, dwS runtime.KeepAlive(lpWindowName) if windows.HWND(r) == 0 { - return 0, fmt.Errorf("goglfw: CreateWindowExW failed: %w", e) + return 0, fmt.Errorf("glfw: CreateWindowExW failed: %w", e) } return windows.HWND(r), nil } @@ -987,7 +987,7 @@ func _DefWindowProcW(hWnd windows.HWND, uMsg uint32, wParam _WPARAM, lParam _LPA func _DestroyIcon(hIcon _HICON) error { r, _, e := procDestroyIcon.Call(uintptr(hIcon)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: DestroyIcon failed: %w", e) + return fmt.Errorf("glfw: DestroyIcon failed: %w", e) } return nil } @@ -995,7 +995,7 @@ func _DestroyIcon(hIcon _HICON) error { func _DestroyWindow(hWnd windows.HWND) error { r, _, e := procDestroyWindow.Call(uintptr(hWnd)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: DestroyWindow failed: %w", e) + return fmt.Errorf("glfw: DestroyWindow failed: %w", e) } return nil } @@ -1003,7 +1003,7 @@ func _DestroyWindow(hWnd windows.HWND) error { func _DeleteObject(ho _HGDIOBJ) error { r, _, e := procDeleteObject.Call(uintptr(ho)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: DeleteObject failed: %w", e) + return fmt.Errorf("glfw: DeleteObject failed: %w", e) } return nil } @@ -1011,7 +1011,7 @@ func _DeleteObject(ho _HGDIOBJ) error { func _DescribePixelFormat(hdc _HDC, iPixelFormat int32, nBytes uint32, ppfd *_PIXELFORMATDESCRIPTOR) (int32, error) { r, _, e := procDescribePixelFormat.Call(uintptr(hdc), uintptr(iPixelFormat), uintptr(nBytes), uintptr(unsafe.Pointer(ppfd))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return 0, fmt.Errorf("goglfw: DescribePixelFormat failed: %w", e) + return 0, fmt.Errorf("glfw: DescribePixelFormat failed: %w", e) } return int32(r), nil } @@ -1054,7 +1054,7 @@ func _DragQueryPoint(hDrop _HDROP) (_POINT, bool) { func _DwmEnableBlurBehindWindow(hWnd windows.HWND, pBlurBehind *_DWM_BLURBEHIND) error { r, _, _ := procDwmEnableBlurBehindWindow.Call(uintptr(hWnd), uintptr(unsafe.Pointer(pBlurBehind))) if uint32(r) != uint32(windows.S_OK) { - return fmt.Errorf("goglfw: DwmEnableBlurBehindWindow failed: %w", handleError(windows.Handle(uint32(r)))) + return fmt.Errorf("glfw: DwmEnableBlurBehindWindow failed: %w", handleError(windows.Handle(uint32(r)))) } return nil } @@ -1064,7 +1064,7 @@ func _DwmGetColorizationColor() (uint32, bool, error) { var opaqueBlend int32 r, _, _ := procDwmGetColorizationColor.Call(uintptr(unsafe.Pointer(&colorization)), uintptr(unsafe.Pointer(&opaqueBlend))) if uint32(r) != uint32(windows.S_OK) { - return 0, false, fmt.Errorf("goglfw: DwmGetColorizationColor failed: %w", handleError(windows.Handle(uint32(r)))) + return 0, false, fmt.Errorf("glfw: DwmGetColorizationColor failed: %w", handleError(windows.Handle(uint32(r)))) } return colorization, opaqueBlend != 0, nil } @@ -1072,7 +1072,7 @@ func _DwmGetColorizationColor() (uint32, bool, error) { func _DwmFlush() error { r, _, _ := procDwmFlush.Call() if uint32(r) != uint32(windows.S_OK) { - return fmt.Errorf("goglfw: DwmFlush failed: %w", handleError(windows.Handle(uint32(r)))) + return fmt.Errorf("glfw: DwmFlush failed: %w", handleError(windows.Handle(uint32(r)))) } return nil } @@ -1081,7 +1081,7 @@ func _DwmIsCompositionEnabled() (bool, error) { var enabled int32 r, _, _ := procDwmIsCompositionEnabled.Call(uintptr(unsafe.Pointer(&enabled))) if uint32(r) != uint32(windows.S_OK) { - return false, fmt.Errorf("goglfw: DwmIsCompositionEnabled failed: %w", handleError(windows.Handle(uint32(r)))) + return false, fmt.Errorf("glfw: DwmIsCompositionEnabled failed: %w", handleError(windows.Handle(uint32(r)))) } return enabled != 0, nil } @@ -1089,7 +1089,7 @@ func _DwmIsCompositionEnabled() (bool, error) { func _EnableNonClientDpiScaling(hwnd windows.HWND) error { r, _, e := procEnableNonClientDpiScaling.Call(uintptr(hwnd)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: EnableNonClientDpiScaling failed: %w", e) + return fmt.Errorf("glfw: EnableNonClientDpiScaling failed: %w", e) } return nil } @@ -1100,7 +1100,7 @@ func _EnumDisplayDevicesW(device string, iDevNum uint32, dwFlags uint32) (_DISPL var err error lpDevice, err = windows.UTF16PtrFromString(device) if err != nil { - panic("goglfw: device name must not include a NUL character") + panic("glfw: device name must not include a NUL character") } } @@ -1118,7 +1118,7 @@ func _EnumDisplayDevicesW(device string, iDevNum uint32, dwFlags uint32) (_DISPL func _EnumDisplayMonitors(hdc _HDC, lprcClip *_RECT, lpfnEnum uintptr, dwData _LPARAM) error { r, _, e := procEnumDisplayMonitors.Call(uintptr(hdc), uintptr(unsafe.Pointer(lprcClip)), uintptr(lpfnEnum), uintptr(dwData)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: EnumDisplayMonitors failed: %w", e) + return fmt.Errorf("glfw: EnumDisplayMonitors failed: %w", e) } return nil } @@ -1129,7 +1129,7 @@ func _EnumDisplaySettingsExW(deviceName string, iModeNum uint32, dwFlags uint32) var err error lpszDeviceName, err = windows.UTF16PtrFromString(deviceName) if err != nil { - panic("goglfw: device name must not include a NUL character") + panic("glfw: device name must not include a NUL character") } } @@ -1151,7 +1151,7 @@ func _EnumDisplaySettingsW(deviceName string, iModeNum uint32) (_DEVMODEW, bool) var err error lpszDeviceName, err = windows.UTF16PtrFromString(deviceName) if err != nil { - panic("goglfw: device name must not include a NUL character") + panic("glfw: device name must not include a NUL character") } } @@ -1184,7 +1184,7 @@ func _GetActiveWindow() windows.HWND { func _GetClassLongPtrW(hWnd windows.HWND, nIndex int32) (uintptr, error) { r, _, e := procGetClassLongPtrW.Call(uintptr(hWnd), uintptr(nIndex)) if r == 0 { - return 0, fmt.Errorf("goglfw: GetClassLongPtrW failed: %w", e) + return 0, fmt.Errorf("glfw: GetClassLongPtrW failed: %w", e) } return r, nil } @@ -1193,7 +1193,7 @@ func _GetClientRect(hWnd windows.HWND) (_RECT, error) { var rect _RECT r, _, e := procGetClientRect.Call(uintptr(hWnd), uintptr(unsafe.Pointer(&rect))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return _RECT{}, fmt.Errorf("goglfw: GetClientRect failed: %w", e) + return _RECT{}, fmt.Errorf("glfw: GetClientRect failed: %w", e) } return rect, nil } @@ -1202,7 +1202,7 @@ func _GetCursorPos() (_POINT, error) { var point _POINT r, _, e := procGetCursorPos.Call(uintptr(unsafe.Pointer(&point))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return _POINT{}, fmt.Errorf("goglfw: GetCursorPos failed: %w", e) + return _POINT{}, fmt.Errorf("glfw: GetCursorPos failed: %w", e) } return point, nil } @@ -1210,7 +1210,7 @@ func _GetCursorPos() (_POINT, error) { func _GetDC(hWnd windows.HWND) (_HDC, error) { r, _, e := procGetDC.Call(uintptr(hWnd)) if _HDC(r) == 0 { - return 0, fmt.Errorf("goglfw: GetDC failed: %w", e) + return 0, fmt.Errorf("glfw: GetDC failed: %w", e) } return _HDC(r), nil } @@ -1233,7 +1233,7 @@ func _GetKeyState(nVirtKey int32) int16 { func _GetLayeredWindowAttributes(hWnd windows.HWND) (key _COLORREF, alpha byte, flags uint32, err error) { r, _, e := procGetLayeredWindowAttributes.Call(uintptr(hWnd), uintptr(unsafe.Pointer(&key)), uintptr(unsafe.Pointer(&alpha)), uintptr(unsafe.Pointer(&flags))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return 0, 0, 0, fmt.Errorf("goglfw: GetLayeredWindowAttributes failed: %w", e) + return 0, 0, 0, fmt.Errorf("glfw: GetLayeredWindowAttributes failed: %w", e) } return } @@ -1250,14 +1250,14 @@ func _GetModuleHandleExW(dwFlags uint32, lpModuleName any) (_HMODULE, error) { if moduleName != "" { p, err := windows.UTF16PtrFromString(moduleName) if err != nil { - panic("goglfw: module name must not include a NUL character") + panic("glfw: module name must not include a NUL character") } ptr = unsafe.Pointer(p) } case unsafe.Pointer: ptr = moduleName default: - return 0, fmt.Errorf("goglfw: GetModuleHandleExW: lpModuleName must be a string or an unsafe.Pointer but %T", moduleName) + return 0, fmt.Errorf("glfw: GetModuleHandleExW: lpModuleName must be a string or an unsafe.Pointer but %T", moduleName) } var module _HMODULE @@ -1265,7 +1265,7 @@ func _GetModuleHandleExW(dwFlags uint32, lpModuleName any) (_HMODULE, error) { runtime.KeepAlive(ptr) if int32(r) != 1 { - return 0, fmt.Errorf("goglfw: GetModuleHandleExW failed: %w", e) + return 0, fmt.Errorf("glfw: GetModuleHandleExW failed: %w", e) } return module, nil } @@ -1293,7 +1293,7 @@ func _GetMonitorInfoW_Ex(hMonitor _HMONITOR) (_MONITORINFOEXW, bool) { func _GetDpiForMonitor(hmonitor _HMONITOR, dpiType _MONITOR_DPI_TYPE) (dpiX, dpiY uint32, err error) { r, _, _ := procGetDpiForMonitor.Call(uintptr(hmonitor), uintptr(dpiType), uintptr(unsafe.Pointer(&dpiX)), uintptr(unsafe.Pointer(&dpiY))) if uint32(r) != uint32(windows.S_OK) { - return 0, 0, fmt.Errorf("goglfw: GetDpiForMonitor failed: %w", handleError(windows.Handle(uint32(r)))) + return 0, 0, fmt.Errorf("glfw: GetDpiForMonitor failed: %w", handleError(windows.Handle(uint32(r)))) } return dpiX, dpiY, nil } @@ -1301,7 +1301,7 @@ func _GetDpiForMonitor(hmonitor _HMONITOR, dpiType _MONITOR_DPI_TYPE) (dpiX, dpi func _GetRawInputData(hRawInput _HRAWINPUT, uiCommand uint32, pData unsafe.Pointer, pcbSize *uint32) (uint32, error) { r, _, e := procGetRawInputData.Call(uintptr(hRawInput), uintptr(uiCommand), uintptr(pData), uintptr(unsafe.Pointer(pcbSize)), unsafe.Sizeof(_RAWINPUTHEADER{})) if uint32(r) == (1<<32)-1 { - return 0, fmt.Errorf("goglfw: GetRawInputData failed: %w", e) + return 0, fmt.Errorf("glfw: GetRawInputData failed: %w", e) } return uint32(r), nil } @@ -1309,7 +1309,7 @@ func _GetRawInputData(hRawInput _HRAWINPUT, uiCommand uint32, pData unsafe.Point func _GetSystemMetrics(nIndex int32) (int32, error) { r, _, e := procGetSystemMetrics.Call(uintptr(nIndex)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return 0, fmt.Errorf("goglfw: GetSystemMetrics failed: %w", e) + return 0, fmt.Errorf("glfw: GetSystemMetrics failed: %w", e) } return int32(r), nil } @@ -1317,7 +1317,7 @@ func _GetSystemMetrics(nIndex int32) (int32, error) { func _GetSystemMetricsForDpi(nIndex int32, dpi uint32) (int32, error) { r, _, e := procGetSystemMetricsForDpi.Call(uintptr(nIndex), uintptr(dpi)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return 0, fmt.Errorf("goglfw: GetSystemMetrics failed: %w", e) + return 0, fmt.Errorf("glfw: GetSystemMetrics failed: %w", e) } return int32(r), nil } @@ -1325,7 +1325,7 @@ func _GetSystemMetricsForDpi(nIndex int32, dpi uint32) (int32, error) { func _GetWindowLongW(hWnd windows.HWND, nIndex int32) (int32, error) { r, _, e := procGetWindowLongW.Call(uintptr(hWnd), uintptr(nIndex)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return 0, fmt.Errorf("goglfw: GetWindowLongW failed: %w", e) + return 0, fmt.Errorf("glfw: GetWindowLongW failed: %w", e) } return int32(r), nil } @@ -1336,7 +1336,7 @@ func _GetWindowPlacement(hWnd windows.HWND) (_WINDOWPLACEMENT, error) { r, _, e := procGetWindowPlacement.Call(uintptr(hWnd), uintptr(unsafe.Pointer(&wp))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return _WINDOWPLACEMENT{}, fmt.Errorf("goglfw: GetWindowPlacement failed: %w", e) + return _WINDOWPLACEMENT{}, fmt.Errorf("glfw: GetWindowPlacement failed: %w", e) } return wp, nil } @@ -1345,7 +1345,7 @@ func _GetWindowRect(hWnd windows.HWND) (_RECT, error) { var rect _RECT r, _, e := procGetWindowRect.Call(uintptr(hWnd), uintptr(unsafe.Pointer(&rect))) if int(r) == 0 { - return _RECT{}, fmt.Errorf("goglfw: GetWindowRect failed: %w", e) + return _RECT{}, fmt.Errorf("glfw: GetWindowRect failed: %w", e) } return rect, nil } @@ -1368,7 +1368,7 @@ func _IsZoomed(hWnd windows.HWND) bool { func _LoadCursorW(hInstance _HINSTANCE, lpCursorName uintptr) (_HCURSOR, error) { r, _, e := procLoadCursorW.Call(uintptr(hInstance), lpCursorName) if _HCURSOR(r) == 0 { - return 0, fmt.Errorf("goglfw: LoadCursorW: %w", e) + return 0, fmt.Errorf("glfw: LoadCursorW: %w", e) } return _HCURSOR(r), nil } @@ -1376,7 +1376,7 @@ func _LoadCursorW(hInstance _HINSTANCE, lpCursorName uintptr) (_HCURSOR, error) func _LoadImageW(hInst _HINSTANCE, name uintptr, typ uint32, cx int32, cy int32, fuLoad uint32) (windows.Handle, error) { r, _, e := procLoadImageW.Call(uintptr(hInst), name, uintptr(typ), uintptr(cx), uintptr(cy), uintptr(fuLoad)) if windows.Handle(r) == 0 { - return 0, fmt.Errorf("goglfw: LoadImageW: %w", e) + return 0, fmt.Errorf("glfw: LoadImageW: %w", e) } return windows.Handle(r), nil } @@ -1398,7 +1398,7 @@ func _MoveWindow(hWnd windows.HWND, x, y, nWidth, nHeight int32, repaint bool) e } r, _, e := procMoveWindow.Call(uintptr(hWnd), uintptr(x), uintptr(y), uintptr(nWidth), uintptr(nHeight), bRepaint) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: MoveWindow: %w", e) + return fmt.Errorf("glfw: MoveWindow: %w", e) } return nil } @@ -1410,7 +1410,7 @@ func _MsgWaitForMultipleObjects(nCount uint32, pHandles *windows.Handle, waitAll } r, _, e := procMsgWaitForMultipleObjects.Call(uintptr(nCount), uintptr(unsafe.Pointer(pHandles)), fWaitAll, uintptr(dwMilliseconds), uintptr(dwWakeMask)) if uint32(r) == _WAIT_FAILED { - return 0, fmt.Errorf("goglfw: MsgWaitForMultipleObjects failed: %w", e) + return 0, fmt.Errorf("glfw: MsgWaitForMultipleObjects failed: %w", e) } return uint32(r), nil } @@ -1428,7 +1428,7 @@ func _PeekMessageW(lpMsg *_MSG, hWnd windows.HWND, wMsgFilterMin uint32, wMsgFil func _PostMessageW(hWnd windows.HWND, msg uint32, wParam _WPARAM, lParam _LPARAM) error { r, _, e := procPostMessageW.Call(uintptr(hWnd), uintptr(msg), uintptr(wParam), uintptr(lParam)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: PostMessageW failed: %w", e) + return fmt.Errorf("glfw: PostMessageW failed: %w", e) } return nil } @@ -1445,7 +1445,7 @@ func _PtInRect(lprc *_RECT, pt _POINT) bool { // Adjust the alignment for ARM. r, _, _ = procPtInRect.Call(uintptr(unsafe.Pointer(lprc)), 0, uintptr(pt.x), uintptr(pt.y)) default: - panic(fmt.Sprintf("goglfw: GOARCH=%s is not supported", runtime.GOARCH)) + panic(fmt.Sprintf("glfw: GOARCH=%s is not supported", runtime.GOARCH)) } } return int32(r) != 0 @@ -1454,7 +1454,7 @@ func _PtInRect(lprc *_RECT, pt _POINT) bool { func _RegisterClassExW(unnamedParam1 *_WNDCLASSEXW) (_ATOM, error) { r, _, e := procRegisterClassExW.Call(uintptr(unsafe.Pointer(unnamedParam1))) if _ATOM(r) == 0 { - return 0, fmt.Errorf("goglfw: RegisterClassExW failed: %w", e) + return 0, fmt.Errorf("glfw: RegisterClassExW failed: %w", e) } return _ATOM(r), nil } @@ -1462,7 +1462,7 @@ func _RegisterClassExW(unnamedParam1 *_WNDCLASSEXW) (_ATOM, error) { func _RegisterDeviceNotificationW(hRecipient windows.Handle, notificationFilter unsafe.Pointer, flags uint32) (_HDEVNOTIFY, error) { r, _, e := procRegisterDeviceNotificationW.Call(uintptr(hRecipient), uintptr(notificationFilter), uintptr(flags)) if _HDEVNOTIFY(r) == 0 { - return 0, fmt.Errorf("goglfw: RegisterDeviceNotificationW failed: %w", e) + return 0, fmt.Errorf("glfw: RegisterDeviceNotificationW failed: %w", e) } return _HDEVNOTIFY(r), nil } @@ -1474,7 +1474,7 @@ func _RegisterRawInputDevices(pRawInputDevices []_RAWINPUTDEVICE) error { } r, _, e := procRegisterRawInputDevices.Call(uintptr(rawInputDevices), uintptr(len(pRawInputDevices)), unsafe.Sizeof(_RAWINPUTDEVICE{})) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: RegisterRawInputDevices failed: %w", e) + return fmt.Errorf("glfw: RegisterRawInputDevices failed: %w", e) } return nil } @@ -1482,7 +1482,7 @@ func _RegisterRawInputDevices(pRawInputDevices []_RAWINPUTDEVICE) error { func _ReleaseCapture() error { r, _, e := procReleaseCapture.Call() if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: ReleaseCapture failed: %w", e) + return fmt.Errorf("glfw: ReleaseCapture failed: %w", e) } return nil } @@ -1495,7 +1495,7 @@ func _ReleaseDC(hWnd windows.HWND, hDC _HDC) int32 { func _ScreenToClient(hWnd windows.HWND, lpPoint *_POINT) error { r, _, e := procScreenToClient.Call(uintptr(hWnd), uintptr(unsafe.Pointer(lpPoint))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: ScreenToClient failed: %w", e) + return fmt.Errorf("glfw: ScreenToClient failed: %w", e) } return nil } @@ -1518,7 +1518,7 @@ func _SetCursor(hCursor _HCURSOR) _HCURSOR { func _SetCursorPos(x, y int32) error { r, _, e := procSetCursorPos.Call(uintptr(x), uintptr(y)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: SetCursorPos failed: %w", e) + return fmt.Errorf("glfw: SetCursorPos failed: %w", e) } return nil } @@ -1526,7 +1526,7 @@ func _SetCursorPos(x, y int32) error { func _SetFocus(hWnd windows.HWND) (windows.HWND, error) { r, _, e := procSetFocus.Call(uintptr(hWnd)) if windows.HWND(r) == 0 { - return 0, fmt.Errorf("goglfw: SetFocus failed: %w", e) + return 0, fmt.Errorf("glfw: SetFocus failed: %w", e) } return windows.HWND(r), nil } @@ -1539,7 +1539,7 @@ func _SetForegroundWindow(hWnd windows.HWND) bool { func _SetLayeredWindowAttributes(hwnd windows.HWND, crKey _COLORREF, bAlpha byte, dwFlags uint32) error { r, _, e := procSetLayeredWindowAttributes.Call(uintptr(hwnd), uintptr(crKey), uintptr(bAlpha), uintptr(dwFlags)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: SetLayeredWindowAttributes failed: %w", e) + return fmt.Errorf("glfw: SetLayeredWindowAttributes failed: %w", e) } return nil } @@ -1547,7 +1547,7 @@ func _SetLayeredWindowAttributes(hwnd windows.HWND, crKey _COLORREF, bAlpha byte func _SetPixelFormat(hdc _HDC, format int32, ppfd *_PIXELFORMATDESCRIPTOR) error { r, _, e := procSetPixelFormat.Call(uintptr(hdc), uintptr(format), uintptr(unsafe.Pointer(ppfd))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: SetPixelFormat failed: %w", e) + return fmt.Errorf("glfw: SetPixelFormat failed: %w", e) } return nil } @@ -1560,7 +1560,7 @@ func _SetProcessDPIAware() bool { func _SetProcessDpiAwareness(value _PROCESS_DPI_AWARENESS) error { r, _, _ := procSetProcessDpiAwareness.Call(uintptr(value)) if uint32(r) != uint32(windows.S_OK) { - return fmt.Errorf("goglfw: SetProcessDpiAwareness failed: %w", handleError(windows.Handle(uint32(r)))) + return fmt.Errorf("glfw: SetProcessDpiAwareness failed: %w", handleError(windows.Handle(uint32(r)))) } return nil } @@ -1568,7 +1568,7 @@ func _SetProcessDpiAwareness(value _PROCESS_DPI_AWARENESS) error { func _SetProcessDpiAwarenessContext(value _DPI_AWARENESS_CONTEXT) error { r, _, e := procSetProcessDpiAwarenessContext.Call(uintptr(value)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: SetProcessDpiAwarenessContext failed: %w", e) + return fmt.Errorf("glfw: SetProcessDpiAwarenessContext failed: %w", e) } return nil } @@ -1581,7 +1581,7 @@ func _SetThreadExecutionState(esFlags _EXECUTION_STATE) _EXECUTION_STATE { func _SetWindowLongW(hWnd windows.HWND, nIndex int32, dwNewLong int32) (int32, error) { r, _, e := procSetWindowLongW.Call(uintptr(hWnd), uintptr(nIndex), uintptr(dwNewLong)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return 0, fmt.Errorf("goglfw: SetWindowLongW failed: %w", e) + return 0, fmt.Errorf("glfw: SetWindowLongW failed: %w", e) } return int32(r), nil } @@ -1589,7 +1589,7 @@ func _SetWindowLongW(hWnd windows.HWND, nIndex int32, dwNewLong int32) (int32, e func _SetWindowPlacement(hWnd windows.HWND, lpwndpl *_WINDOWPLACEMENT) error { r, _, e := procSetWindowPlacement.Call(uintptr(hWnd), uintptr(unsafe.Pointer(lpwndpl))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: SetWindowPlacement failed: %w", e) + return fmt.Errorf("glfw: SetWindowPlacement failed: %w", e) } return nil } @@ -1597,7 +1597,7 @@ func _SetWindowPlacement(hWnd windows.HWND, lpwndpl *_WINDOWPLACEMENT) error { func _SetWindowPos(hWnd windows.HWND, hWndInsertAfter windows.HWND, x, y, cx, cy int32, uFlags uint32) error { r, _, e := procSetWindowPos.Call(uintptr(hWnd), uintptr(hWndInsertAfter), uintptr(x), uintptr(y), uintptr(cx), uintptr(cy), uintptr(uFlags)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: SetWindowPos failed: %w", e) + return fmt.Errorf("glfw: SetWindowPos failed: %w", e) } return nil } @@ -1606,14 +1606,14 @@ func _SetWindowTextW(hWnd windows.HWND, str string) error { // An empty string is also a valid value. Always create an uint16 pointer. lpString, err := windows.UTF16PtrFromString(str) if err != nil { - panic("goglfw: str must not include a NUL character") + panic("glfw: str must not include a NUL character") } r, _, e := procSetWindowTextW.Call(uintptr(hWnd), uintptr(unsafe.Pointer(lpString))) runtime.KeepAlive(lpString) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: SetWindowTextW failed: %w", e) + return fmt.Errorf("glfw: SetWindowTextW failed: %w", e) } return nil } @@ -1626,7 +1626,7 @@ func _ShowWindow(hWnd windows.HWND, nCmdShow int32) bool { func _SwapBuffers(unnamedParam1 _HDC) error { r, _, e := procSwapBuffers.Call(uintptr(unnamedParam1)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: SwapBuffers failed: %w", e) + return fmt.Errorf("glfw: SwapBuffers failed: %w", e) } return nil } @@ -1634,7 +1634,7 @@ func _SwapBuffers(unnamedParam1 _HDC) error { func _SystemParametersInfoW(uiAction uint32, uiParam uint32, pvParam uintptr, fWinIni uint32) error { r, _, e := procSystemParametersInfoW.Call(uintptr(uiAction), uintptr(uiParam), pvParam, uintptr(fWinIni)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: SystemParametersInfoW failed: %w", e) + return fmt.Errorf("glfw: SystemParametersInfoW failed: %w", e) } return nil } @@ -1642,7 +1642,7 @@ func _SystemParametersInfoW(uiAction uint32, uiParam uint32, pvParam uintptr, fW func _TlsAlloc() (uint32, error) { r, _, e := procTlsAlloc.Call() if uint32(r) == _TLS_OUT_OF_INDEXES { - return 0, fmt.Errorf("goglfw: TlsAlloc failed: %w", e) + return 0, fmt.Errorf("glfw: TlsAlloc failed: %w", e) } return uint32(r), nil } @@ -1650,7 +1650,7 @@ func _TlsAlloc() (uint32, error) { func _TlsFree(dwTlsIndex uint32) error { r, _, e := procTlsFree.Call(uintptr(dwTlsIndex)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: TlsFree failed: %w", e) + return fmt.Errorf("glfw: TlsFree failed: %w", e) } return nil } @@ -1658,7 +1658,7 @@ func _TlsFree(dwTlsIndex uint32) error { func _TlsGetValue(dwTlsIndex uint32) (uintptr, error) { r, _, e := procTlsGetValue.Call(uintptr(dwTlsIndex)) if r == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return 0, fmt.Errorf("goglfw: TlsGetValue failed: %w", e) + return 0, fmt.Errorf("glfw: TlsGetValue failed: %w", e) } return r, nil } @@ -1666,7 +1666,7 @@ func _TlsGetValue(dwTlsIndex uint32) (uintptr, error) { func _TlsSetValue(dwTlsIndex uint32, lpTlsValue uintptr) error { r, _, e := procTlsSetValue.Call(uintptr(dwTlsIndex), lpTlsValue) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: TlsSetValue failed: %w", e) + return fmt.Errorf("glfw: TlsSetValue failed: %w", e) } return nil } @@ -1697,7 +1697,7 @@ func _TranslateMessage(lpMsg *_MSG) bool { func _TrackMouseEvent(lpEventTrack *_TRACKMOUSEEVENT) error { r, _, e := procTrackMouseEvent.Call(uintptr(unsafe.Pointer(lpEventTrack))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: TrackMouseEvent failed: %w", e) + return fmt.Errorf("glfw: TrackMouseEvent failed: %w", e) } return nil } @@ -1708,7 +1708,7 @@ func _UnregisterClassW(className string, hInstance _HINSTANCE) error { var err error lpClassName, err = windows.UTF16PtrFromString(className) if err != nil { - panic("goglfw: class name must not include a NUL character") + panic("glfw: class name must not include a NUL character") } } @@ -1716,7 +1716,7 @@ func _UnregisterClassW(className string, hInstance _HINSTANCE) error { runtime.KeepAlive(lpClassName) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: UnregisterClassW failed: %w", e) + return fmt.Errorf("glfw: UnregisterClassW failed: %w", e) } return nil } @@ -1724,7 +1724,7 @@ func _UnregisterClassW(className string, hInstance _HINSTANCE) error { func _UnregisterDeviceNotification(handle _HDEVNOTIFY) error { r, _, e := procUnregisterDeviceNotification.Call(uintptr(handle)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: UnregisterDeviceNotification failed: %w", e) + return fmt.Errorf("glfw: UnregisterDeviceNotification failed: %w", e) } return nil } @@ -1732,7 +1732,7 @@ func _UnregisterDeviceNotification(handle _HDEVNOTIFY) error { func _WaitMessage() error { r, _, e := procWaitMessage.Call() if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: WaitMessage failed: %w", e) + return fmt.Errorf("glfw: WaitMessage failed: %w", e) } return nil } @@ -1740,7 +1740,7 @@ func _WaitMessage() error { func wglCreateContext(unnamedParam1 _HDC) (_HGLRC, error) { r, _, e := procWGLCreateContext.Call(uintptr(unnamedParam1)) if _HGLRC(r) == 0 { - return 0, fmt.Errorf("goglfw: wglCreateContext failed: %w", e) + return 0, fmt.Errorf("glfw: wglCreateContext failed: %w", e) } return _HGLRC(r), nil } @@ -1749,7 +1749,7 @@ func wglCreateContextAttribsARB(hDC _HDC, hshareContext _HGLRC, attribList *int3 r, _, e := syscall.Syscall(procWGLCreateContextAttribsARB, 3, uintptr(hDC), uintptr(hshareContext), uintptr(unsafe.Pointer(attribList))) if _HGLRC(r) == 0 { // TODO: Show more detailed error? See the original implementation. - return 0, fmt.Errorf("goglfw: wglCreateContextAttribsARB failed: %w", e) + return 0, fmt.Errorf("glfw: wglCreateContextAttribsARB failed: %w", e) } return _HGLRC(r), nil } @@ -1757,7 +1757,7 @@ func wglCreateContextAttribsARB(hDC _HDC, hshareContext _HGLRC, attribList *int3 func wglDeleteContext(unnamedParam1 _HGLRC) error { r, _, e := procWGLDeleteContext.Call(uintptr(unnamedParam1)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: wglDeleteContext failed: %w", e) + return fmt.Errorf("glfw: wglDeleteContext failed: %w", e) } return nil } @@ -1793,7 +1793,7 @@ func wglGetExtensionsStringEXT_Available() bool { func wglGetPixelFormatAttribivARB(hdc _HDC, iPixelFormat int32, iLayerPlane int32, nAttributes uint32, piAttributes *int32, piValues *int32) error { r, _, e := syscall.Syscall6(procWGLGetPixelFormatAttribivARB, 6, uintptr(hdc), uintptr(iPixelFormat), uintptr(iLayerPlane), uintptr(nAttributes), uintptr(unsafe.Pointer(piAttributes)), uintptr(unsafe.Pointer(piValues))) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: wglGetPixelFormatAttribivARB failed: %w", e) + return fmt.Errorf("glfw: wglGetPixelFormatAttribivARB failed: %w", e) } return nil } @@ -1801,7 +1801,7 @@ func wglGetPixelFormatAttribivARB(hdc _HDC, iPixelFormat int32, iLayerPlane int3 func wglGetProcAddress(unnamedParam1 string) uintptr { ptr, err := windows.BytePtrFromString(unnamedParam1) if err != nil { - panic("goglfw: unnamedParam1 must not include a NUL character") + panic("glfw: unnamedParam1 must not include a NUL character") } r, _, _ := procWGLGetProcAddress.Call(uintptr(unsafe.Pointer(ptr))) return r @@ -1810,7 +1810,7 @@ func wglGetProcAddress(unnamedParam1 string) uintptr { func wglMakeCurrent(unnamedParam1 _HDC, unnamedParam2 _HGLRC) error { r, _, e := procWGLMakeCurrent.Call(uintptr(unnamedParam1), uintptr(unnamedParam2)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: wglMakeCurrent failed: %w", e) + return fmt.Errorf("glfw: wglMakeCurrent failed: %w", e) } return nil } @@ -1818,7 +1818,7 @@ func wglMakeCurrent(unnamedParam1 _HDC, unnamedParam2 _HGLRC) error { func wglShareLists(unnamedParam1 _HGLRC, unnamedParam2 _HGLRC) error { r, _, e := procWGLShareLists.Call(uintptr(unnamedParam1), uintptr(unnamedParam2)) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: wglShareLists failed: %w", e) + return fmt.Errorf("glfw: wglShareLists failed: %w", e) } return nil } @@ -1826,7 +1826,7 @@ func wglShareLists(unnamedParam1 _HGLRC, unnamedParam2 _HGLRC) error { func wglSwapIntervalEXT(interval int32) error { r, _, e := syscall.Syscall(procWGLSwapIntervalEXT, 1, uintptr(interval), 0, 0) if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) { - return fmt.Errorf("goglfw: wglSwapIntervalEXT failed: %w", e) + return fmt.Errorf("glfw: wglSwapIntervalEXT failed: %w", e) } return nil } diff --git a/internal/glfw/callback_goglfw.go b/internal/glfw/callback_windows.go similarity index 55% rename from internal/glfw/callback_goglfw.go rename to internal/glfw/callback_windows.go index da22e931e..717a04910 100644 --- a/internal/glfw/callback_goglfw.go +++ b/internal/glfw/callback_windows.go @@ -16,69 +16,30 @@ package glfw -import ( - "github.com/hajimehoshi/ebiten/v2/internal/goglfw" -) - func ToCharModsCallback(cb func(window *Window, char rune, mods ModifierKey)) CharModsCallback { - if cb == nil { - return nil - } - return func(window *goglfw.Window, char rune, mods goglfw.ModifierKey) { - cb((*Window)(window), char, ModifierKey(mods)) - } + return cb } func ToCloseCallback(cb func(window *Window)) CloseCallback { - if cb == nil { - return nil - } - return func(window *goglfw.Window) { - cb((*Window)(window)) - } + return cb } func ToDropCallback(cb func(window *Window, names []string)) DropCallback { - if cb == nil { - return nil - } - return func(window *goglfw.Window, names []string) { - cb((*Window)(window), names) - } + return cb } func ToFramebufferSizeCallback(cb func(window *Window, width int, height int)) FramebufferSizeCallback { - if cb == nil { - return nil - } - return func(window *goglfw.Window, width int, height int) { - cb((*Window)(window), width, height) - } + return cb } func ToMonitorCallback(cb func(monitor *Monitor, event PeripheralEvent)) MonitorCallback { - if cb == nil { - return nil - } - return func(monitor *goglfw.Monitor, event goglfw.PeripheralEvent) { - cb((*Monitor)(monitor), PeripheralEvent(event)) - } + return cb } func ToScrollCallback(cb func(window *Window, xoff float64, yoff float64)) ScrollCallback { - if cb == nil { - return nil - } - return func(window *goglfw.Window, xoff float64, yoff float64) { - cb((*Window)(window), xoff, yoff) - } + return cb } func ToSizeCallback(cb func(window *Window, width int, height int)) SizeCallback { - if cb == nil { - return nil - } - return func(window *goglfw.Window, width int, height int) { - cb((*Window)(window), width, height) - } + return cb } diff --git a/internal/goglfw/context_windows.go b/internal/glfw/context_windows.go similarity index 86% rename from internal/goglfw/context_windows.go rename to internal/glfw/context_windows.go index daa6c090c..2f7ea8d10 100644 --- a/internal/goglfw/context_windows.go +++ b/internal/glfw/context_windows.go @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2006-2019 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw import ( "fmt" @@ -26,13 +26,13 @@ func checkValidContextConfig(ctxconfig *ctxconfig) error { if ctxconfig.source != NativeContextAPI && ctxconfig.source != EGLContextAPI && ctxconfig.source != OSMesaContextAPI { - return fmt.Errorf("goglfw: invalid context creation API 0x%08X: %w", ctxconfig.source, InvalidEnum) + return fmt.Errorf("glfw: invalid context creation API 0x%08X: %w", ctxconfig.source, InvalidEnum) } if ctxconfig.client != NoAPI && ctxconfig.client != OpenGLAPI && ctxconfig.client != OpenGLESAPI { - return fmt.Errorf("goglfw: invalid client API 0x%08X: %w", ctxconfig.client, InvalidEnum) + return fmt.Errorf("glfw: invalid client API 0x%08X: %w", ctxconfig.client, InvalidEnum) } if ctxconfig.client == OpenGLAPI { @@ -46,25 +46,25 @@ func checkValidContextConfig(ctxconfig *ctxconfig) error { // OpenGL 3.x series ended with version 3.3 // For now, let everything else through - return fmt.Errorf("goglfw: invalid OpenGL version %d.%d: %w", ctxconfig.major, ctxconfig.minor, InvalidValue) + return fmt.Errorf("glfw: invalid OpenGL version %d.%d: %w", ctxconfig.major, ctxconfig.minor, InvalidValue) } if ctxconfig.profile != 0 { if ctxconfig.profile != OpenGLCoreProfile && ctxconfig.profile != OpenGLCompatProfile { - return fmt.Errorf("goglfw: invalid OpenGL profile 0x%08X: %w", ctxconfig.profile, InvalidEnum) + return fmt.Errorf("glfw: invalid OpenGL profile 0x%08X: %w", ctxconfig.profile, InvalidEnum) } if ctxconfig.major <= 2 || (ctxconfig.major == 3 && ctxconfig.minor < 2) { // Desktop OpenGL context profiles are only defined for version 3.2 // and above - return fmt.Errorf("goglfw: context profiles are only defined for OpenGL version 3.2 and above: %w", InvalidValue) + return fmt.Errorf("glfw: context profiles are only defined for OpenGL version 3.2 and above: %w", InvalidValue) } } if ctxconfig.forward && ctxconfig.major <= 2 { // Forward-compatible contexts are only defined for OpenGL version 3.0 and above - return fmt.Errorf("goglfw: forward-compatibility is only defined for OpenGL version 3.0 and above: %w", InvalidValue) + return fmt.Errorf("glfw: forward-compatibility is only defined for OpenGL version 3.0 and above: %w", InvalidValue) } } else if ctxconfig.client == OpenGLESAPI { if ctxconfig.major < 1 || ctxconfig.minor < 0 || @@ -75,19 +75,19 @@ func checkValidContextConfig(ctxconfig *ctxconfig) error { // OpenGL ES 2.x series ended with version 2.0 // For now, let everything else through - return fmt.Errorf("goglfw: invalid OpenGL ES version %d.%d: %w", ctxconfig.major, ctxconfig.minor, InvalidValue) + return fmt.Errorf("glfw: invalid OpenGL ES version %d.%d: %w", ctxconfig.major, ctxconfig.minor, InvalidValue) } } if ctxconfig.robustness != 0 { if ctxconfig.robustness != NoResetNotification && ctxconfig.robustness != LoseContextOnReset { - return fmt.Errorf("goglfw: invalid context robustness mode 0x%08X: %w", ctxconfig.robustness, InvalidEnum) + return fmt.Errorf("glfw: invalid context robustness mode 0x%08X: %w", ctxconfig.robustness, InvalidEnum) } } if ctxconfig.release != 0 { if ctxconfig.release != ReleaseBehaviorNone && ctxconfig.release != ReleaseBehaviorFlush { - return fmt.Errorf("goglfw: invalid context release behavior 0x%08X: %w", ctxconfig.release, InvalidEnum) + return fmt.Errorf("glfw: invalid context release behavior 0x%08X: %w", ctxconfig.release, InvalidEnum) } } @@ -267,16 +267,16 @@ func (w *Window) refreshContextAttribs(ctxconfig *ctxconfig) (ferr error) { getIntegerv := w.context.getProcAddress("glGetIntegerv") getString := w.context.getProcAddress("glGetString") if getIntegerv == 0 || getString == 0 { - return fmt.Errorf("goglfw: entry point retrieval is broken: %w", PlatformError) + return fmt.Errorf("glfw: entry point retrieval is broken: %w", PlatformError) } r, _, _ := purego.SyscallN(getString, GL_VERSION) version := bytePtrToString((*byte)(unsafe.Pointer(r))) if version == "" { if ctxconfig.client == OpenGLAPI { - return fmt.Errorf("goglfw: OpenGL version string retrieval is broken: %w", PlatformError) + return fmt.Errorf("glfw: OpenGL version string retrieval is broken: %w", PlatformError) } else { - return fmt.Errorf("goglfw: OpenGL ES version string retrieval is broken: %w", PlatformError) + return fmt.Errorf("glfw: OpenGL ES version string retrieval is broken: %w", PlatformError) } } @@ -294,9 +294,9 @@ func (w *Window) refreshContextAttribs(ctxconfig *ctxconfig) (ferr error) { m := regexp.MustCompile(`^(\d+)(\.(\d+)(\.(\d+))?)?`).FindStringSubmatch(version) if m == nil { if w.context.client == OpenGLAPI { - return fmt.Errorf("goglfw: no version found in OpenGL version string: %w", PlatformError) + return fmt.Errorf("glfw: no version found in OpenGL version string: %w", PlatformError) } else { - return fmt.Errorf("goglfw: no version found in OpenGL ES version string: %w", PlatformError) + return fmt.Errorf("glfw: no version found in OpenGL ES version string: %w", PlatformError) } } w.context.major, _ = strconv.Atoi(m[1]) @@ -312,9 +312,9 @@ func (w *Window) refreshContextAttribs(ctxconfig *ctxconfig) (ferr error) { // {GLX|WGL}_ARB_create_context extension and fail here if w.context.client == OpenGLAPI { - return fmt.Errorf("goglfw: requested OpenGL version %d.%d, got version %d.%d: %w", ctxconfig.major, ctxconfig.minor, w.context.major, w.context.minor, VersionUnavailable) + return fmt.Errorf("glfw: requested OpenGL version %d.%d, got version %d.%d: %w", ctxconfig.major, ctxconfig.minor, w.context.major, w.context.minor, VersionUnavailable) } else { - return fmt.Errorf("goglfw: requested OpenGL ES version %d.%d, got version %d.%d: %w", ctxconfig.major, ctxconfig.minor, w.context.major, w.context.minor, VersionUnavailable) + return fmt.Errorf("glfw: requested OpenGL ES version %d.%d, got version %d.%d: %w", ctxconfig.major, ctxconfig.minor, w.context.major, w.context.minor, VersionUnavailable) } } @@ -325,7 +325,7 @@ func (w *Window) refreshContextAttribs(ctxconfig *ctxconfig) (ferr error) { glGetStringi := w.context.getProcAddress("glGetStringi") if glGetStringi == 0 { - return fmt.Errorf("goglfw: entry point retrieval is broken: %w", PlatformError) + return fmt.Errorf("glfw: entry point retrieval is broken: %w", PlatformError) } } @@ -463,7 +463,7 @@ func (w *Window) MakeContextCurrent() error { previous := (*Window)(unsafe.Pointer(ptr)) if w != nil && w.context.client == NoAPI { - return fmt.Errorf("goglfw: cannot make current with a window that has no OpenGL or OpenGL ES context: %w", NoWindowContext) + return fmt.Errorf("glfw: cannot make current with a window that has no OpenGL or OpenGL ES context: %w", NoWindowContext) } if previous != nil { @@ -499,7 +499,7 @@ func (w *Window) SwapBuffers() error { } if w.context.client == NoAPI { - return fmt.Errorf("goglfw: cannot swap buffers of a window that has no OpenGL or OpenGL ES context: %w", NoWindowContext) + return fmt.Errorf("glfw: cannot swap buffers of a window that has no OpenGL or OpenGL ES context: %w", NoWindowContext) } if err := w.context.swapBuffers(w); err != nil { @@ -519,7 +519,7 @@ func SwapInterval(interval int) error { } window := (*Window)(unsafe.Pointer(ptr)) if window == nil { - return fmt.Errorf("goglfw: cannot set swap interval without a current OpenGL or OpenGL ES context %w", NoCurrentContext) + return fmt.Errorf("glfw: cannot set swap interval without a current OpenGL or OpenGL ES context %w", NoCurrentContext) } if err := window.context.swapInterval(interval); err != nil { @@ -544,7 +544,7 @@ func ExtensionSupported(extension string) (bool, error) { } window := (*Window)(unsafe.Pointer(ptr)) if window == nil { - return false, fmt.Errorf("goglfw: cannot query extension without a current OpenGL or OpenGL ES context %w", NoCurrentContext) + return false, fmt.Errorf("glfw: cannot query extension without a current OpenGL or OpenGL ES context %w", NoCurrentContext) } if window.context.major >= 3 { @@ -558,7 +558,7 @@ func ExtensionSupported(extension string) (bool, error) { for i := 0; i < int(count); i++ { r, _, _ := purego.SyscallN(glGetStringi, GL_EXTENSIONS, uintptr(i)) if r == 0 { - return false, fmt.Errorf("goglfw: extension string retrieval is broken: %w", PlatformError) + return false, fmt.Errorf("glfw: extension string retrieval is broken: %w", PlatformError) } en := bytePtrToString((*byte)(unsafe.Pointer(r))) @@ -572,7 +572,7 @@ func ExtensionSupported(extension string) (bool, error) { glGetString := window.context.getProcAddress("glGetString") r, _, _ := purego.SyscallN(glGetString, GL_EXTENSIONS) if r == 0 { - return false, fmt.Errorf("goglfw: extension string retrieval is broken: %w", PlatformError) + return false, fmt.Errorf("glfw: extension string retrieval is broken: %w", PlatformError) } extensions := bytePtrToString((*byte)(unsafe.Pointer(r))) diff --git a/internal/glfw/glfw3h_windows.go b/internal/glfw/glfw3h_windows.go new file mode 100644 index 000000000..f295e1369 --- /dev/null +++ b/internal/glfw/glfw3h_windows.go @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2002-2006 Marcus Geelnard +// SPDX-FileCopyrightText: 2006-2019 Camilla Löwy +// SPDX-FileCopyrightText: 2022 The Ebitengine Authors + +package glfw + +type VidMode struct { + Width int + Height int + RedBits int + GreenBits int + BlueBits int + RefreshRate int +} + +type Image struct { + Width int + Height int + Pixels []byte +} diff --git a/internal/glfw/glfw_cglfw.go b/internal/glfw/glfw_cglfw.go index 8c5d93ba8..9a1e9c30e 100644 --- a/internal/glfw/glfw_cglfw.go +++ b/internal/glfw/glfw_cglfw.go @@ -61,9 +61,9 @@ type Cursor struct { c *cglfw.Cursor } -func CreateStandardCursor(shape StandardCursor) *Cursor { +func CreateStandardCursor(shape StandardCursor) (*Cursor, error) { c := cglfw.CreateStandardCursor(cglfw.StandardCursor(shape)) - return &Cursor{c: c} + return &Cursor{c: c}, nil } type Monitor struct { @@ -75,14 +75,15 @@ func (m *Monitor) GetContentScale() (float32, float32, error) { return x, y, nil } -func (m *Monitor) GetPos() (x, y int) { - return m.m.GetPos() +func (m *Monitor) GetPos() (x, y int, err error) { + x, y = m.m.GetPos() + return } -func (m *Monitor) GetVideoMode() *VidMode { +func (m *Monitor) GetVideoMode() (*VidMode, error) { v := m.m.GetVideoMode() if v == nil { - return nil + return nil, nil } return &VidMode{ Width: v.Width, @@ -91,11 +92,11 @@ func (m *Monitor) GetVideoMode() *VidMode { GreenBits: v.GreenBits, BlueBits: v.BlueBits, RefreshRate: v.RefreshRate, - } + }, nil } -func (m *Monitor) GetName() string { - return m.m.GetName() +func (m *Monitor) GetName() (string, error) { + return m.m.GetName(), nil } type Window struct { @@ -109,164 +110,181 @@ func (w *Window) Destroy() { theWindows.remove(w.w) } -func (w *Window) Focus() { +func (w *Window) Focus() error { w.w.Focus() + return nil } -func (w *Window) GetAttrib(attrib Hint) int { - return w.w.GetAttrib(cglfw.Hint(attrib)) +func (w *Window) GetAttrib(attrib Hint) (int, error) { + return w.w.GetAttrib(cglfw.Hint(attrib)), nil } -func (w *Window) GetCursorPos() (x, y float64) { - return w.w.GetCursorPos() +func (w *Window) GetCursorPos() (x, y float64, err error) { + x, y = w.w.GetCursorPos() + return } -func (w *Window) GetInputMode(mode InputMode) int { - return w.w.GetInputMode(cglfw.InputMode(mode)) +func (w *Window) GetInputMode(mode InputMode) (int, error) { + return w.w.GetInputMode(cglfw.InputMode(mode)), nil } -func (w *Window) GetKey(key Key) Action { - return Action(w.w.GetKey(cglfw.Key(key))) +func (w *Window) GetKey(key Key) (Action, error) { + return Action(w.w.GetKey(cglfw.Key(key))), nil } -func (w *Window) GetMonitor() *Monitor { +func (w *Window) GetMonitor() (*Monitor, error) { m := w.w.GetMonitor() if m == nil { - return nil + return nil, nil } - return &Monitor{m} + return &Monitor{m}, nil } -func (w *Window) GetMouseButton(button MouseButton) Action { - return Action(w.w.GetMouseButton(cglfw.MouseButton(button))) +func (w *Window) GetMouseButton(button MouseButton) (Action, error) { + return Action(w.w.GetMouseButton(cglfw.MouseButton(button))), nil } -func (w *Window) GetPos() (x, y int) { - return w.w.GetPos() +func (w *Window) GetPos() (x, y int, err error) { + x, y = w.w.GetPos() + return } -func (w *Window) GetSize() (width, height int) { - return w.w.GetSize() +func (w *Window) GetSize() (width, height int, err error) { + width, height = w.w.GetSize() + return } func (w *Window) Hide() { w.w.Hide() } -func (w *Window) Iconify() { +func (w *Window) Iconify() error { w.w.Iconify() + return nil } -func (w *Window) MakeContextCurrent() { +func (w *Window) MakeContextCurrent() error { w.w.MakeContextCurrent() + return nil } -func (w *Window) Maximize() { +func (w *Window) Maximize() error { w.w.Maximize() + return nil } -func (w *Window) Restore() { +func (w *Window) Restore() error { w.w.Restore() + return nil } -func (w *Window) SetAttrib(attrib Hint, value int) { +func (w *Window) SetAttrib(attrib Hint, value int) error { w.w.SetAttrib(cglfw.Hint(attrib), value) + return nil } -func (w *Window) SetCharModsCallback(cbfun CharModsCallback) (previous CharModsCallback) { +func (w *Window) SetCharModsCallback(cbfun CharModsCallback) (previous CharModsCallback, err error) { w.w.SetCharModsCallback(cbfun) - return ToCharModsCallback(nil) // TODO + return ToCharModsCallback(nil), nil // TODO } -func (w *Window) SetCloseCallback(cbfun CloseCallback) (previous CloseCallback) { +func (w *Window) SetCloseCallback(cbfun CloseCallback) (previous CloseCallback, err error) { w.w.SetCloseCallback(cbfun) - return ToCloseCallback(nil) // TODO + return ToCloseCallback(nil), nil // TODO } -func (w *Window) SetCursor(cursor *Cursor) { +func (w *Window) SetCursor(cursor *Cursor) error { var c *cglfw.Cursor if cursor != nil { c = cursor.c } w.w.SetCursor(c) + return nil } -func (w *Window) SetCursorPos(xpos, ypos float64) { +func (w *Window) SetCursorPos(xpos, ypos float64) error { w.w.SetCursorPos(xpos, ypos) + return nil } -func (w *Window) SetDropCallback(cbfun DropCallback) (previous DropCallback) { +func (w *Window) SetDropCallback(cbfun DropCallback) (previous DropCallback, err error) { w.w.SetDropCallback(cbfun) - return ToDropCallback(nil) // TODO + return ToDropCallback(nil), nil // TODO } -func (w *Window) SetFramebufferSizeCallback(cbfun FramebufferSizeCallback) (previous FramebufferSizeCallback) { +func (w *Window) SetFramebufferSizeCallback(cbfun FramebufferSizeCallback) (previous FramebufferSizeCallback, err error) { w.w.SetFramebufferSizeCallback(cbfun) - return ToFramebufferSizeCallback(nil) // TODO + return ToFramebufferSizeCallback(nil), nil // TODO } -func (w *Window) SetScrollCallback(cbfun ScrollCallback) (previous ScrollCallback) { +func (w *Window) SetScrollCallback(cbfun ScrollCallback) (previous ScrollCallback, err error) { w.w.SetScrollCallback(cbfun) - return ToScrollCallback(nil) // TODO + return ToScrollCallback(nil), nil // TODO } -func (w *Window) SetShouldClose(value bool) { +func (w *Window) SetShouldClose(value bool) error { w.w.SetShouldClose(value) + return nil } -func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous SizeCallback) { +func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous SizeCallback, err error) { w.w.SetSizeCallback(cbfun) prev := w.prevSizeCallback w.prevSizeCallback = cbfun - return prev + return prev, nil } -func (w *Window) SetSizeLimits(minw, minh, maxw, maxh int) { +func (w *Window) SetSizeLimits(minw, minh, maxw, maxh int) error { w.w.SetSizeLimits(minw, minh, maxw, maxh) + return nil } -func (w *Window) SetAspectRatio(numer, denom int) { - w.w.SetAspectRatio(numer, denom) -} - -func (w *Window) SetIcon(images []image.Image) { +func (w *Window) SetIcon(images []image.Image) error { w.w.SetIcon(images) + return nil } -func (w *Window) SetInputMode(mode InputMode, value int) { +func (w *Window) SetInputMode(mode InputMode, value int) error { w.w.SetInputMode(cglfw.InputMode(mode), value) + return nil } -func (w *Window) SetMonitor(monitor *Monitor, xpos, ypos, width, height, refreshRate int) { +func (w *Window) SetMonitor(monitor *Monitor, xpos, ypos, width, height, refreshRate int) error { var m *cglfw.Monitor if monitor != nil { m = monitor.m } w.w.SetMonitor(m, xpos, ypos, width, height, refreshRate) + return nil } -func (w *Window) SetPos(xpos, ypos int) { +func (w *Window) SetPos(xpos, ypos int) error { w.w.SetPos(xpos, ypos) + return nil } -func (w *Window) SetSize(width, height int) { +func (w *Window) SetSize(width, height int) error { w.w.SetSize(width, height) + return nil } -func (w *Window) SetTitle(title string) { +func (w *Window) SetTitle(title string) error { w.w.SetTitle(title) + return nil } -func (w *Window) ShouldClose() bool { - return w.w.ShouldClose() +func (w *Window) ShouldClose() (bool, error) { + return w.w.ShouldClose(), nil } -func (w *Window) Show() { +func (w *Window) Show() error { w.w.Show() + return nil } -func (w *Window) SwapBuffers() { +func (w *Window) SwapBuffers() error { w.w.SwapBuffers() + return nil } func CreateWindow(width, height int, title string, monitor *Monitor, share *Window) (*Window, error) { @@ -286,12 +304,12 @@ func CreateWindow(width, height int, title string, monitor *Monitor, share *Wind return theWindows.add(w), nil } -func GetKeyName(key Key, scancode int) string { - return cglfw.GetKeyName(cglfw.Key(key), scancode) +func GetKeyName(key Key, scancode int) (string, error) { + return cglfw.GetKeyName(cglfw.Key(key), scancode), nil } -func GetMonitors() []*Monitor { - ms := []*Monitor{} +func GetMonitors() ([]*Monitor, error) { + var ms []*Monitor for _, m := range cglfw.GetMonitors() { if m != nil { ms = append(ms, &Monitor{m}) @@ -299,7 +317,7 @@ func GetMonitors() []*Monitor { ms = append(ms, nil) } } - return ms + return ms, nil } func GetPrimaryMonitor() *Monitor { @@ -314,35 +332,41 @@ func Init() error { return cglfw.Init() } -func PollEvents() { +func PollEvents() error { cglfw.PollEvents() + return nil } -func PostEmptyEvent() { +func PostEmptyEvent() error { cglfw.PostEmptyEvent() + return nil } -func SetMonitorCallback(cbfun MonitorCallback) MonitorCallback { +func SetMonitorCallback(cbfun MonitorCallback) (MonitorCallback, error) { cglfw.SetMonitorCallback(cbfun) - return ToMonitorCallback(nil) + return ToMonitorCallback(nil), nil } -func SwapInterval(interval int) { +func SwapInterval(interval int) error { cglfw.SwapInterval(interval) + return nil } -func Terminate() { +func Terminate() error { cglfw.Terminate() + return nil } -func WaitEvents() { +func WaitEvents() error { cglfw.WaitEvents() + return nil } func WaitEventsTimeout(timeout float64) { cglfw.WaitEventsTimeout(timeout) } -func WindowHint(target Hint, hint int) { +func WindowHint(target Hint, hint int) error { cglfw.WindowHint(cglfw.Hint(target), hint) + return nil } diff --git a/internal/glfw/glfw_goglfw.go b/internal/glfw/glfw_goglfw.go deleted file mode 100644 index 75ffce304..000000000 --- a/internal/glfw/glfw_goglfw.go +++ /dev/null @@ -1,416 +0,0 @@ -// Copyright 2018 The Ebiten Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build windows - -package glfw - -import ( - "errors" - "image" - "image/draw" - - "github.com/hajimehoshi/ebiten/v2/internal/goglfw" -) - -type Cursor goglfw.Cursor - -func CreateStandardCursor(shape StandardCursor) *Cursor { - c, err := goglfw.CreateStandardCursor(goglfw.StandardCursor(shape)) - if err != nil { - panic(err) - } - return (*Cursor)(c) -} - -type Monitor goglfw.Monitor - -func (m *Monitor) GetContentScale() (float32, float32, error) { - return (*goglfw.Monitor)(m).GetContentScale() -} - -func (m *Monitor) GetPos() (int, int) { - x, y, err := (*goglfw.Monitor)(m).GetPos() - if err != nil { - panic(err) - } - return x, y -} - -func (m *Monitor) GetVideoMode() *VidMode { - v, err := (*goglfw.Monitor)(m).GetVideoMode() - if err != nil { - panic(err) - } - return (*VidMode)(v) -} - -func (m *Monitor) GetName() string { - v, err := (*goglfw.Monitor)(m).GetName() - if err != nil { - panic(err) - } - return v -} - -type Window goglfw.Window - -func (w *Window) Destroy() { - if err := (*goglfw.Window)(w).Destroy(); err != nil { - panic(err) - } -} - -func (w *Window) Focus() { - if err := (*goglfw.Window)(w).Focus(); err != nil { - panic(err) - } -} - -func (w *Window) GetAttrib(attrib Hint) int { - r, err := (*goglfw.Window)(w).GetAttrib(goglfw.Hint(attrib)) - if err != nil { - panic(err) - } - return r -} - -func (w *Window) GetCursorPos() (x, y float64) { - x, y, err := (*goglfw.Window)(w).GetCursorPos() - if err != nil { - panic(err) - } - return x, y -} - -func (w *Window) GetInputMode(mode InputMode) int { - r, err := (*goglfw.Window)(w).GetInputMode(goglfw.InputMode(mode)) - if err != nil { - panic(err) - } - return r -} - -func (w *Window) GetKey(key Key) Action { - r, err := (*goglfw.Window)(w).GetKey(goglfw.Key(key)) - if err != nil { - panic(err) - } - return Action(r) -} - -func (w *Window) GetMonitor() *Monitor { - m, err := (*goglfw.Window)(w).GetMonitor() - if err != nil { - panic(err) - } - return (*Monitor)(m) -} - -func (w *Window) GetMouseButton(button MouseButton) Action { - r, err := (*goglfw.Window)(w).GetMouseButton(goglfw.MouseButton(button)) - if err != nil { - panic(err) - } - return Action(r) -} - -func (w *Window) GetPos() (int, int) { - x, y, err := (*goglfw.Window)(w).GetPos() - if err != nil { - panic(err) - } - return x, y -} - -func (w *Window) GetSize() (int, int) { - width, height, err := (*goglfw.Window)(w).GetSize() - if err != nil { - panic(err) - } - return width, height -} - -func (w *Window) Hide() { - if err := (*goglfw.Window)(w).Hide(); err != nil { - panic(err) - } -} - -func (w *Window) Iconify() { - if err := (*goglfw.Window)(w).Iconify(); err != nil { - panic(err) - } -} - -func (w *Window) MakeContextCurrent() { - if err := (*goglfw.Window)(w).MakeContextCurrent(); err != nil { - panic(err) - } -} - -func (w *Window) Maximize() { - if err := (*goglfw.Window)(w).Maximize(); err != nil { - panic(err) - } -} - -func (w *Window) Restore() { - if err := (*goglfw.Window)(w).Restore(); err != nil { - panic(err) - } -} - -func (w *Window) SetAttrib(attrib Hint, value int) { - if err := (*goglfw.Window)(w).SetAttrib(goglfw.Hint(attrib), value); err != nil { - panic(err) - } -} - -func (w *Window) SetCharModsCallback(cbfun CharModsCallback) (previous CharModsCallback) { - f, err := (*goglfw.Window)(w).SetCharModsCallback(cbfun) - if err != nil { - panic(err) - } - return f -} - -func (w *Window) SetCloseCallback(cbfun CloseCallback) (previous CloseCallback) { - f, err := (*goglfw.Window)(w).SetCloseCallback(cbfun) - if err != nil { - panic(err) - } - return f -} - -func (w *Window) SetCursor(cursor *Cursor) { - if err := (*goglfw.Window)(w).SetCursor((*goglfw.Cursor)(cursor)); err != nil { - panic(err) - } -} - -func (w *Window) SetCursorPos(xpos, ypos float64) { - if err := (*goglfw.Window)(w).SetCursorPos(xpos, ypos); err != nil { - panic(err) - } -} - -func (w *Window) SetDropCallback(cbfun DropCallback) (previous DropCallback) { - f, err := (*goglfw.Window)(w).SetDropCallback(cbfun) - if err != nil { - panic(err) - } - return f -} - -func (w *Window) SetFramebufferSizeCallback(cbfun FramebufferSizeCallback) (previous FramebufferSizeCallback) { - f, err := (*goglfw.Window)(w).SetFramebufferSizeCallback(cbfun) - if err != nil { - panic(err) - } - return f -} - -func (w *Window) SetScrollCallback(cbfun ScrollCallback) (previous ScrollCallback) { - f, err := (*goglfw.Window)(w).SetScrollCallback(cbfun) - if err != nil { - panic(err) - } - return f -} - -func (w *Window) SetShouldClose(value bool) { - if err := (*goglfw.Window)(w).SetShouldClose(value); err != nil { - panic(err) - } -} - -func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous SizeCallback) { - f, err := (*goglfw.Window)(w).SetSizeCallback(cbfun) - if err != nil { - panic(err) - } - return f -} - -func (w *Window) SetSizeLimits(minw, minh, maxw, maxh int) { - if err := (*goglfw.Window)(w).SetSizeLimits(minw, minh, maxw, maxh); err != nil { - panic(err) - } -} - -func (w *Window) SetAspectRatio(numer, denom int) { - if err := (*goglfw.Window)(w).SetAspectRatio(numer, denom); err != nil { - panic(err) - } -} - -func (w *Window) SetIcon(images []image.Image) { - gimgs := make([]*goglfw.Image, len(images)) - for i, img := range images { - b := img.Bounds() - m := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) - draw.Draw(m, m.Bounds(), img, b.Min, draw.Src) - gimgs[i] = &goglfw.Image{ - Width: b.Dx(), - Height: b.Dy(), - Pixels: m.Pix, - } - } - - if err := (*goglfw.Window)(w).SetIcon(gimgs); err != nil { - panic(err) - } -} - -func (w *Window) SetInputMode(mode InputMode, value int) { - if err := (*goglfw.Window)(w).SetInputMode(goglfw.InputMode(mode), value); err != nil { - panic(err) - } -} - -func (w *Window) SetMonitor(monitor *Monitor, xpos, ypos, width, height, refreshRate int) { - if err := (*goglfw.Window)(w).SetMonitor((*goglfw.Monitor)(monitor), xpos, ypos, width, height, refreshRate); err != nil { - panic(err) - } -} - -func (w *Window) SetPos(xpos, ypos int) { - if err := (*goglfw.Window)(w).SetPos(xpos, ypos); err != nil { - panic(err) - } -} - -func (w *Window) SetSize(width, height int) { - if err := (*goglfw.Window)(w).SetSize(width, height); err != nil { - panic(err) - } -} - -func (w *Window) SetTitle(title string) { - if err := (*goglfw.Window)(w).SetTitle(title); err != nil { - panic(err) - } -} - -func (w *Window) ShouldClose() bool { - r, err := (*goglfw.Window)(w).ShouldClose() - if err != nil { - panic(err) - } - return r -} - -func (w *Window) Show() { - if err := (*goglfw.Window)(w).Show(); err != nil { - panic(err) - } -} - -func (w *Window) SwapBuffers() { - if err := (*goglfw.Window)(w).SwapBuffers(); err != nil { - panic(err) - } -} - -func CreateWindow(width, height int, title string, monitor *Monitor, share *Window) (*Window, error) { - w, err := goglfw.CreateWindow(width, height, title, (*goglfw.Monitor)(monitor), (*goglfw.Window)(share)) - // TODO: acceptError(APIUnavailable, VersionUnavailable)? - return (*Window)(w), err -} - -func GetKeyName(key Key, scancode int) string { - name, err := goglfw.GetKeyName(goglfw.Key(key), scancode) - if err != nil { - panic(err) - } - return name -} - -func GetMonitors() []*Monitor { - ms, err := goglfw.GetMonitors() - if err != nil { - panic(err) - } - result := make([]*Monitor, 0, len(ms)) - for _, m := range ms { - result = append(result, (*Monitor)(m)) - } - return result -} - -func GetPrimaryMonitor() *Monitor { - m, err := goglfw.GetPrimaryMonitor() - if err != nil { - panic(err) - } - return (*Monitor)(m) -} - -func Init() error { - // InvalidValue can happen when specific joysticks are used. This issue - // will be fixed in GLFW 3.3.5. As a temporary fix, ignore this error. - // See go-gl/glfw#292, go-gl/glfw#324, and glfw/glfw#1763 - // (#1229). - // TODO: acceptError(APIUnavailable, InvalidValue)? - err := goglfw.Init() - if err != nil && !errors.Is(err, goglfw.InvalidValue) { - return err - } - return nil -} - -func PollEvents() { - if err := goglfw.PollEvents(); err != nil && !errors.Is(err, goglfw.InvalidValue) { - panic(err) - } -} - -func PostEmptyEvent() { - if err := goglfw.PostEmptyEvent(); err != nil { - panic(err) - } -} - -func SetMonitorCallback(cbfun MonitorCallback) MonitorCallback { - f, err := goglfw.SetMonitorCallback(cbfun) - if err != nil { - panic(err) - } - return f -} - -func SwapInterval(interval int) { - if err := goglfw.SwapInterval(interval); err != nil { - panic(err) - } -} - -func Terminate() { - if err := goglfw.Terminate(); err != nil { - panic(err) - } -} - -func WaitEvents() { - if err := goglfw.WaitEvents(); err != nil { - panic(err) - } -} - -func WindowHint(target Hint, hint int) { - if err := goglfw.WindowHint(goglfw.Hint(target), hint); err != nil { - panic(err) - } -} diff --git a/internal/goglfw/init_windows.go b/internal/glfw/init_windows.go similarity index 78% rename from internal/goglfw/init_windows.go rename to internal/glfw/init_windows.go index 53a0ba39a..3a80ddca0 100644 --- a/internal/goglfw/init_windows.go +++ b/internal/glfw/init_windows.go @@ -3,7 +3,11 @@ // SPDX-FileCopyrightText: 2006-2018 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw + +import ( + "errors" +) func terminate() error { for _, w := range _glfw.windows { @@ -36,6 +40,14 @@ func terminate() error { func Init() (ferr error) { defer func() { if ferr != nil { + // InvalidValue can happen when specific joysticks are used. This issue + // will be fixed in GLFW 3.3.5. As a temporary fix, ignore this error. + // See go-gl/glfw#292, go-gl/glfw#324, and glfw/glfw#1763 + // (#1229). + if errors.Is(ferr, InvalidValue) { + ferr = nil + return + } _ = terminate() } }() diff --git a/internal/goglfw/input_windows.go b/internal/glfw/input_windows.go similarity index 93% rename from internal/goglfw/input_windows.go rename to internal/glfw/input_windows.go index 4e9a4bfcd..4632c3189 100644 --- a/internal/goglfw/input_windows.go +++ b/internal/glfw/input_windows.go @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2006-2019 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw import ( "fmt" @@ -142,7 +142,7 @@ func (w *Window) GetInputMode(mode InputMode) (int, error) { case RawMouseMotion: return boolToInt(w.rawMouseMotion), nil default: - return 0, fmt.Errorf("goglfw: invalid input mode 0x%08X: %w", mode, InvalidEnum) + return 0, fmt.Errorf("glfw: invalid input mode 0x%08X: %w", mode, InvalidEnum) } } @@ -154,7 +154,7 @@ func (w *Window) SetInputMode(mode InputMode, value int) error { switch mode { case CursorMode: if value != CursorNormal && value != CursorHidden && value != CursorDisabled { - return fmt.Errorf("goglfw: invalid cursor mode 0x%08X: %w", value, InvalidEnum) + return fmt.Errorf("glfw: invalid cursor mode 0x%08X: %w", value, InvalidEnum) } if w.cursorMode == value { @@ -215,7 +215,7 @@ func (w *Window) SetInputMode(mode InputMode, value int) error { case RawMouseMotion: if !platformRawMouseMotionSupported() { - return fmt.Errorf("goglfw: raw mouse motion is not supported on this system: %w", PlatformError) + return fmt.Errorf("glfw: raw mouse motion is not supported on this system: %w", PlatformError) } if w.rawMouseMotion == intToBool(value) { @@ -229,7 +229,7 @@ func (w *Window) SetInputMode(mode InputMode, value int) error { return nil default: - return fmt.Errorf("goglfw: invalid input mode 0x%08X: %w", mode, InvalidEnum) + return fmt.Errorf("glfw: invalid input mode 0x%08X: %w", mode, InvalidEnum) } } @@ -261,7 +261,7 @@ func GetKeyScancode(key Key) (int, error) { } if key < KeySpace || key > KeyLast { - return 0, fmt.Errorf("goglfw: invalid key %d: %w", key, InvalidEnum) + return 0, fmt.Errorf("glfw: invalid key %d: %w", key, InvalidEnum) } return platformGetKeyScancode(key), nil @@ -273,7 +273,7 @@ func (w *Window) GetKey(key Key) (Action, error) { } if key < KeySpace || key > KeyLast { - return 0, fmt.Errorf("goglfw: invalid key %d: %w", key, InvalidEnum) + return 0, fmt.Errorf("glfw: invalid key %d: %w", key, InvalidEnum) } if w.keys[key] == stick { @@ -291,7 +291,7 @@ func (w *Window) GetMouseButton(button MouseButton) (Action, error) { } if button < MouseButton1 || button > MouseButtonLast { - return 0, fmt.Errorf("goglfw: invalid mouse button %d: %w", button, InvalidEnum) + return 0, fmt.Errorf("glfw: invalid mouse button %d: %w", button, InvalidEnum) } if w.mouseButtons[button] == stick { @@ -321,7 +321,7 @@ func (w *Window) SetCursorPos(xpos, ypos float64) error { } if xpos != xpos || xpos < -math.MaxFloat64 || xpos > math.MaxFloat64 || ypos != ypos || ypos < -math.MaxFloat64 || ypos > math.MaxFloat64 { - return fmt.Errorf("goglfw: invalid cursor position %f %f: %w", xpos, ypos, InvalidValue) + return fmt.Errorf("glfw: invalid cursor position %f %f: %w", xpos, ypos, InvalidValue) } if !w.platformWindowFocused() { @@ -354,7 +354,7 @@ func CreateStandardCursor(shape StandardCursor) (*Cursor, error) { shape != ResizeNESWCursor && shape != ResizeAllCursor && shape != NotAllowedCursor { - return nil, fmt.Errorf("goglfw: invalid standard cursor 0x%08X: %w", shape, InvalidEnum) + return nil, fmt.Errorf("glfw: invalid standard cursor 0x%08X: %w", shape, InvalidEnum) } cursor := &Cursor{} diff --git a/internal/goglfw/internal_windows.go b/internal/glfw/internal_windows.go similarity index 99% rename from internal/goglfw/internal_windows.go rename to internal/glfw/internal_windows.go index 1a80706d7..aca499d14 100644 --- a/internal/goglfw/internal_windows.go +++ b/internal/glfw/internal_windows.go @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2006-2019 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw import ( "unsafe" diff --git a/internal/goglfw/monitor_windows.go b/internal/glfw/monitor_windows.go similarity index 99% rename from internal/goglfw/monitor_windows.go rename to internal/glfw/monitor_windows.go index cec42fe40..d6fa760bd 100644 --- a/internal/goglfw/monitor_windows.go +++ b/internal/glfw/monitor_windows.go @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2006-2019 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw import ( "sort" diff --git a/internal/glfw/native_windows.go b/internal/glfw/native_windows.go deleted file mode 100644 index 0c49ad92b..000000000 --- a/internal/glfw/native_windows.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2018 The Ebiten Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package glfw - -import ( - "github.com/hajimehoshi/ebiten/v2/internal/goglfw" -) - -func (w *Window) GetWin32Window() uintptr { - r, err := (*goglfw.Window)(w).GetWin32Window() - if err != nil { - panic(err) - } - return uintptr(r) -} diff --git a/internal/glfw/type_goglfw.go b/internal/glfw/type_goglfw.go deleted file mode 100644 index d7c84ebf0..000000000 --- a/internal/glfw/type_goglfw.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2018 The Ebiten Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build windows - -package glfw - -import ( - "github.com/hajimehoshi/ebiten/v2/internal/goglfw" -) - -type ( - CharModsCallback = goglfw.CharModsCallback - CloseCallback = goglfw.CloseCallback - DropCallback = goglfw.DropCallback - FramebufferSizeCallback = goglfw.FramebufferSizeCallback - MonitorCallback = goglfw.MonitorCallback - ScrollCallback = goglfw.ScrollCallback - SizeCallback = goglfw.SizeCallback -) - -type VidMode goglfw.VidMode diff --git a/internal/goglfw/wglcontext_windows.go b/internal/glfw/wgl_context_windows.go similarity index 96% rename from internal/goglfw/wglcontext_windows.go rename to internal/glfw/wgl_context_windows.go index ab833fd94..f3aebfb70 100644 --- a/internal/goglfw/wglcontext_windows.go +++ b/internal/glfw/wgl_context_windows.go @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2006-2019 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw import ( "errors" @@ -221,12 +221,12 @@ func (w *Window) choosePixelFormat(ctxconfig *ctxconfig, fbconfig_ *fbconfig) (i } if len(usableConfigs) == 0 { - return 0, fmt.Errorf("goglfw: the driver does not appear to support OpenGL") + return 0, fmt.Errorf("glfw: the driver does not appear to support OpenGL") } closest := chooseFBConfig(fbconfig_, usableConfigs) if closest == nil { - return 0, fmt.Errorf("goglfw: failed to find a suitable pixel format") + return 0, fmt.Errorf("glfw: failed to find a suitable pixel format") } return int(closest.handle), nil @@ -361,7 +361,7 @@ func destroyContextWGL(window *Window) error { func initWGL() error { if microsoftgdk.IsXbox() { - return fmt.Errorf("goglfw: WGL is not available in Xbox") + return fmt.Errorf("glfw: WGL is not available in Xbox") } if _glfw.platformContext.inited { @@ -475,15 +475,15 @@ func (w *Window) createContextWGL(ctxconfig *ctxconfig, fbconfig *fbconfig) erro if ctxconfig.client == OpenGLAPI { if ctxconfig.forward && !_glfw.platformContext.ARB_create_context { - return fmt.Errorf("goglfw: a forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable: %w", VersionUnavailable) + return fmt.Errorf("glfw: a forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable: %w", VersionUnavailable) } if ctxconfig.profile != 0 && !_glfw.platformContext.ARB_create_context_profile { - return fmt.Errorf("goglfw: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable: %w", VersionUnavailable) + return fmt.Errorf("glfw: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable: %w", VersionUnavailable) } } else { if !_glfw.platformContext.ARB_create_context || !_glfw.platformContext.ARB_create_context_profile || !_glfw.platformContext.EXT_create_context_es2_profile { - return fmt.Errorf("goglfw: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable: %w", ApiUnavailable) + return fmt.Errorf("glfw: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable: %w", APIUnavailable) } } diff --git a/internal/goglfw/win32init_windows.go b/internal/glfw/win32_init_windows.go similarity index 99% rename from internal/goglfw/win32init_windows.go rename to internal/glfw/win32_init_windows.go index cc94289df..4e7f5eaa7 100644 --- a/internal/goglfw/win32init_windows.go +++ b/internal/glfw/win32_init_windows.go @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2006-2019 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw import ( "errors" diff --git a/internal/goglfw/win32monitor_windows.go b/internal/glfw/win32_monitor_windows.go similarity index 93% rename from internal/goglfw/win32monitor_windows.go rename to internal/glfw/win32_monitor_windows.go index fd696a8fe..68d7b8c39 100644 --- a/internal/goglfw/win32monitor_windows.go +++ b/internal/glfw/win32_monitor_windows.go @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2021 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw import ( "errors" @@ -189,21 +189,21 @@ func (m *Monitor) setVideoModeWin32(desired *VidMode) error { m.platform.modeChanged = true return nil case _DISP_CHANGE_BADDUALVIEW: - return errors.New("goglfw: the system uses DualView at Monitor.setVideoModeWin32") + return errors.New("glfw: the system uses DualView at Monitor.setVideoModeWin32") case _DISP_CHANGE_BADFLAGS: - return errors.New("goglfw: invalid flags at Monitor.setVideoModeWin32") + return errors.New("glfw: invalid flags at Monitor.setVideoModeWin32") case _DISP_CHANGE_BADMODE: - return errors.New("goglfw: graphics mode not supported at Monitor.setVideoModeWin32") + return errors.New("glfw: graphics mode not supported at Monitor.setVideoModeWin32") case _DISP_CHANGE_BADPARAM: - return errors.New("goglfw: invalid parameter at Monitor.setVideoModeWin32") + return errors.New("glfw: invalid parameter at Monitor.setVideoModeWin32") case _DISP_CHANGE_FAILED: - return errors.New("goglfw: graphics mode failed at Monitor.setVideoModeWin32") + return errors.New("glfw: graphics mode failed at Monitor.setVideoModeWin32") case _DISP_CHANGE_NOTUPDATED: - return errors.New("goglfw: failed to write to registry at Monitor.setVideoModeWin32") + return errors.New("glfw: failed to write to registry at Monitor.setVideoModeWin32") case _DISP_CHANGE_RESTART: - return errors.New("goglfw: computer restart required at Monitor.setVideoModeWin32") + return errors.New("glfw: computer restart required at Monitor.setVideoModeWin32") default: - return errors.New("goglfw: unknown error at Monitor.setVideoModeWin32") + return errors.New("glfw: unknown error at Monitor.setVideoModeWin32") } } diff --git a/internal/goglfw/win32platform_windows.go b/internal/glfw/win32_platform_windows.go similarity index 99% rename from internal/goglfw/win32platform_windows.go rename to internal/glfw/win32_platform_windows.go index 792c2be48..8ba293942 100644 --- a/internal/goglfw/win32platform_windows.go +++ b/internal/glfw/win32_platform_windows.go @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2006-2019 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw import ( "golang.org/x/sys/windows" diff --git a/internal/goglfw/win32thread_windows.go b/internal/glfw/win32_thread_windows.go similarity index 85% rename from internal/goglfw/win32thread_windows.go rename to internal/glfw/win32_thread_windows.go index 915206900..634fe260b 100644 --- a/internal/goglfw/win32thread_windows.go +++ b/internal/glfw/win32_thread_windows.go @@ -3,11 +3,11 @@ // SPDX-FileCopyrightText: 2006-2017 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw func (t *tls) create() error { if t.platform.allocated { - panic("goglfw: TLS must not be allocated") + panic("glfw: TLS must not be allocated") } i, err := _TlsAlloc() @@ -32,7 +32,7 @@ func (t *tls) destroy() error { func (t *tls) get() (uintptr, error) { if !t.platform.allocated { - panic("goglfw: TLS must be allocated") + panic("glfw: TLS must be allocated") } return _TlsGetValue(t.platform.index) @@ -40,7 +40,7 @@ func (t *tls) get() (uintptr, error) { func (t *tls) set(value uintptr) error { if !t.platform.allocated { - panic("goglfw: TLS must be allocated") + panic("glfw: TLS must be allocated") } return _TlsSetValue(t.platform.index, value) diff --git a/internal/goglfw/win32window_windows.go b/internal/glfw/win32_window_windows.go similarity index 99% rename from internal/goglfw/win32window_windows.go rename to internal/glfw/win32_window_windows.go index 81435dba2..56da8abe1 100644 --- a/internal/goglfw/win32window_windows.go +++ b/internal/glfw/win32_window_windows.go @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2006-2019 Camilla Löwy // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw import ( "errors" @@ -1209,7 +1209,7 @@ func (w *Window) createNativeWindow(wndconfig *wndconfig, fbconfig *fbconfig) er if w.monitor != nil { mi, ok := _GetMonitorInfoW(w.monitor.platform.handle) if !ok { - return fmt.Errorf("goglfw: GetMonitorInfoW failed") + return fmt.Errorf("glfw: GetMonitorInfoW failed") } // NOTE: This window placement is temporary and approximate, as the // correct position and size cannot be known until the monitor @@ -1361,7 +1361,7 @@ func registerWindowClassWin32() error { wc.hCursor = cursor className, err := windows.UTF16FromString(_GLFW_WNDCLASSNAME) if err != nil { - panic("goglfw: _GLFW_WNDCLASSNAME must not inclucde a NUL character") + panic("glfw: _GLFW_WNDCLASSNAME must not inclucde a NUL character") } wc.lpszClassName = &className[0] defer runtime.KeepAlive(className) @@ -2303,7 +2303,7 @@ func (c *Cursor) platformCreateStandardCursor(shape StandardCursor) error { case NotAllowedCursor: // v3.4 id = _OCR_NO default: - return fmt.Errorf("goglfw: invalid shape: %d", shape) + return fmt.Errorf("glfw: invalid shape: %d", shape) } h, err := _LoadImageW(0, uintptr(id), _IMAGE_CURSOR, 0, 0, _LR_DEFAULTSIZE|_LR_SHARED) @@ -2338,11 +2338,11 @@ func (w *Window) platformSetCursor(cursor *Cursor) error { } func platformSetClipboardString(str string) error { - panic("goglfw: platformSetClipboardString is not implemented") + panic("glfw: platformSetClipboardString is not implemented") } func platformGetClipboardString() (string, error) { - panic("goglfw: platformGetClipboardString is not implemented") + panic("glfw: platformGetClipboardString is not implemented") } func (w *Window) GetWin32Window() (windows.HWND, error) { diff --git a/internal/goglfw/window_windows.go b/internal/glfw/window_windows.go similarity index 93% rename from internal/goglfw/window_windows.go rename to internal/glfw/window_windows.go index 45ea5e4fe..4ddfdde16 100644 --- a/internal/goglfw/window_windows.go +++ b/internal/glfw/window_windows.go @@ -4,10 +4,12 @@ // SPDX-FileCopyrightText: 2012 Torsten Walluhn // SPDX-FileCopyrightText: 2022 The Ebitengine Authors -package goglfw +package glfw import ( "fmt" + "image" + "image/draw" "math" "unsafe" ) @@ -92,7 +94,7 @@ func CreateWindow(width, height int, title string, monitor *Monitor, share *Wind } if width <= 0 || height <= 0 { - return nil, fmt.Errorf("goglfw: invalid window size %dx%d: %w", width, height, InvalidValue) + return nil, fmt.Errorf("glfw: invalid window size %dx%d: %w", width, height, InvalidValue) } fbconfig := _glfw.hints.framebuffer @@ -276,7 +278,7 @@ func WindowHint(hint Hint, value int) error { case RefreshRate: _glfw.hints.refreshRate = value default: - return fmt.Errorf("goglfw: invalid window hint 0x%08X: %w", hint, InvalidEnum) + return fmt.Errorf("glfw: invalid window hint 0x%08X: %w", hint, InvalidEnum) } return nil } @@ -349,11 +351,24 @@ func (w *Window) SetTitle(title string) error { return nil } -func (w *Window) SetIcon(images []*Image) error { +func (w *Window) SetIcon(images []image.Image) error { if !_glfw.initialized { return NotInitialized } - if err := w.platformSetWindowIcon(images); err != nil { + + gimgs := make([]*Image, len(images)) + for i, img := range images { + b := img.Bounds() + m := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) + draw.Draw(m, m.Bounds(), img, b.Min, draw.Src) + gimgs[i] = &Image{ + Width: b.Dx(), + Height: b.Dy(), + Pixels: m.Pix, + } + } + + if err := w.platformSetWindowIcon(gimgs); err != nil { return err } return nil @@ -405,13 +420,13 @@ func (w *Window) SetSizeLimits(minwidth, minheight, maxwidth, maxheight int) err if minwidth != DontCare && minheight != DontCare { if minwidth < 0 || minheight < 0 { - return fmt.Errorf("goglfw: invalid window minimum size %dx%d: %w", minwidth, minheight, InvalidValue) + return fmt.Errorf("glfw: 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("goglfw: invalid window maximum size %dx%d: %w", maxwidth, maxheight, InvalidValue) + return fmt.Errorf("glfw: invalid window maximum size %dx%d: %w", maxwidth, maxheight, InvalidValue) } } @@ -438,7 +453,7 @@ func (w *Window) SetAspectRatio(numer, denom int) error { if numer != DontCare && denom != DontCare { if numer <= 0 || denom <= 0 { - return fmt.Errorf("goglfw: invalid window aspect ratio %d:%d: %w", numer, denom, InvalidValue) + return fmt.Errorf("glfw: invalid window aspect ratio %d:%d: %w", numer, denom, InvalidValue) } } @@ -489,7 +504,7 @@ func (w *Window) SetOpacity(opacity float32) error { } if opacity != opacity || opacity < 0 || opacity > 1 { - return fmt.Errorf("goglfw: invalid window opacity %f: %w", opacity, InvalidValue) + return fmt.Errorf("glfw: invalid window opacity %f: %w", opacity, InvalidValue) } if err := w.platformSetWindowOpacity(opacity); err != nil { @@ -633,7 +648,7 @@ func (w *Window) GetAttrib(attrib Hint) (int, error) { case ContextNoError: return boolToInt(w.context.noerror), nil default: - return 0, fmt.Errorf("goglfw: invalid window attribute 0x%08X: %w", attrib, InvalidEnum) + return 0, fmt.Errorf("glfw: invalid window attribute 0x%08X: %w", attrib, InvalidEnum) } } @@ -691,7 +706,7 @@ func (w *Window) SetAttrib(attrib Hint, value int) error { } return nil default: - return fmt.Errorf("goglfw: invalid window attribute 0x%08X: %w", attrib, InvalidEnum) + return fmt.Errorf("glfw: invalid window attribute 0x%08X: %w", attrib, InvalidEnum) } } @@ -708,11 +723,11 @@ func (w *Window) SetMonitor(monitor *Monitor, xpos, ypos, width, height, refresh } if width <= 0 || height <= 0 { - return fmt.Errorf("goglfw: invalid window size %dx%d: %w", width, height, InvalidValue) + return fmt.Errorf("glfw: invalid window size %dx%d: %w", width, height, InvalidValue) } if refreshRate < 0 && refreshRate != DontCare { - return fmt.Errorf("goglfw: invalid refresh rate %d: %w", refreshRate, InvalidValue) + return fmt.Errorf("glfw: invalid refresh rate %d: %w", refreshRate, InvalidValue) } w.videoMode.Width = width @@ -846,7 +861,7 @@ func WaitEventsTimeout(timeout float64) error { return NotInitialized } if timeout != timeout || timeout < 0.0 || timeout > math.MaxFloat64 { - return fmt.Errorf("goglfw: invalid time %f: %w", timeout, InvalidValue) + return fmt.Errorf("glfw: invalid time %f: %w", timeout, InvalidValue) } if err := platformWaitEventsTimeout(timeout); err != nil { return err diff --git a/internal/goglfw/glfw3h_windows.go b/internal/goglfw/glfw3h_windows.go deleted file mode 100644 index ee6ddbc38..000000000 --- a/internal/goglfw/glfw3h_windows.go +++ /dev/null @@ -1,341 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2002-2006 Marcus Geelnard -// SPDX-FileCopyrightText: 2006-2019 Camilla Löwy -// SPDX-FileCopyrightText: 2022 The Ebitengine Authors - -package goglfw - -const ( - NoAPI = 0 - OpenGLAPI = 0x00030001 - OpenGLESAPI = 0x00030002 - - NoRobustness = 0 - NoResetNotification = 0x00031001 - LoseContextOnReset = 0x00031002 - - OpenGLAnyProfile = 0 - OpenGLCoreProfile = 0x00032001 - OpenGLCompatProfile = 0x00032002 - - CursorNormal = 0x00034001 - CursorHidden = 0x00034002 - CursorDisabled = 0x00034003 - - AnyReleaseBehavior = 0 - ReleaseBehaviorFlush = 0x00035001 - ReleaseBehaviorNone = 0x00035002 - - NativeContextAPI = 0x00036001 - EGLContextAPI = 0x00036002 - OSMesaContextAPI = 0x00036003 - - DontCare = -1 -) - -type Action int - -const ( - Release Action = 0 - Press Action = 1 - Repeat Action = 2 -) - -type Hint int - -const ( - Focused Hint = 0x00020001 - Iconified Hint = 0x00020002 - Resizable Hint = 0x00020003 - Visible Hint = 0x00020004 - Decorated Hint = 0x00020005 - AutoIconify Hint = 0x00020006 - Floating Hint = 0x00020007 - Maximized Hint = 0x00020008 - CenterCursor Hint = 0x00020009 - TransparentFramebuffer Hint = 0x0002000A - Hovered Hint = 0x0002000B - FocusOnShow Hint = 0x0002000C - MousePassthrough Hint = 0x0002000D - - RedBits Hint = 0x00021001 - GreenBits Hint = 0x00021002 - BlueBits Hint = 0x00021003 - AlphaBits Hint = 0x00021004 - DepthBits Hint = 0x00021005 - StencilBits Hint = 0x00021006 - AccumRedBits Hint = 0x00021007 - AccumGreenBits Hint = 0x00021008 - AccumBlueBits Hint = 0x00021009 - AccumAlphaBits Hint = 0x0002100A - AuxBuffers Hint = 0x0002100B - Stereo Hint = 0x0002100C - Samples Hint = 0x0002100D - SRGBCapable Hint = 0x0002100E - RefreshRate Hint = 0x0002100F - DoubleBuffer Hint = 0x00021010 - - ClientAPI Hint = 0x00022001 - ContextVersionMajor Hint = 0x00022002 - ContextVersionMinor Hint = 0x00022003 - ContextRevision Hint = 0x00022004 - ContextRobustness Hint = 0x00022005 - OpenGLForwardCompat Hint = 0x00022006 - OpenGLDebugContext Hint = 0x00022007 - OpenGLProfile Hint = 0x00022008 - ContextReleaseBehavior Hint = 0x00022009 - ContextNoError Hint = 0x0002200A - ContextCreationAPI Hint = 0x0002200B - ScaleToMonitor Hint = 0x0002200C -) - -type InputMode int - -const ( - CursorMode InputMode = 0x00033001 - StickyKeysMode InputMode = 0x00033002 - StickyMouseButtonsMode InputMode = 0x00033003 - LockKeyMods InputMode = 0x00033004 - RawMouseMotion InputMode = 0x00033005 -) - -type Key int - -const ( - KeyUnknown Key = -1 - - // Printable keys - KeySpace Key = 32 - KeyApostrophe Key = 39 // ' - KeyComma Key = 44 // , - KeyMinus Key = 45 // - - KeyPeriod Key = 46 // . - KeySlash Key = 47 // / - Key0 Key = 48 - Key1 Key = 49 - Key2 Key = 50 - Key3 Key = 51 - Key4 Key = 52 - Key5 Key = 53 - Key6 Key = 54 - Key7 Key = 55 - Key8 Key = 56 - Key9 Key = 57 - KeySemicolon Key = 59 // ; - KeyEqual Key = 61 // = - KeyA Key = 65 - KeyB Key = 66 - KeyC Key = 67 - KeyD Key = 68 - KeyE Key = 69 - KeyF Key = 70 - KeyG Key = 71 - KeyH Key = 72 - KeyI Key = 73 - KeyJ Key = 74 - KeyK Key = 75 - KeyL Key = 76 - KeyM Key = 77 - KeyN Key = 78 - KeyO Key = 79 - KeyP Key = 80 - KeyQ Key = 81 - KeyR Key = 82 - KeyS Key = 83 - KeyT Key = 84 - KeyU Key = 85 - KeyV Key = 86 - KeyW Key = 87 - KeyX Key = 88 - KeyY Key = 89 - KeyZ Key = 90 - KeyLeftBracket Key = 91 // [ - KeyBackslash Key = 92 // \ - KeyRightBracket Key = 93 // ] - KeyGraveAccent Key = 96 // ` - KeyWorld1 Key = 161 // non-US #1 - KeyWorld2 Key = 162 // non-US #2 - - // Function keys - KeyEscape Key = 256 - KeyEnter Key = 257 - KeyTab Key = 258 - KeyBackspace Key = 259 - KeyInsert Key = 260 - KeyDelete Key = 261 - KeyRight Key = 262 - KeyLeft Key = 263 - KeyDown Key = 264 - KeyUp Key = 265 - KeyPageUp Key = 266 - KeyPageDown Key = 267 - KeyHome Key = 268 - KeyEnd Key = 269 - KeyCapsLock Key = 280 - KeyScrollLock Key = 281 - KeyNumLock Key = 282 - KeyPrintScreen Key = 283 - KeyPause Key = 284 - KeyF1 Key = 290 - KeyF2 Key = 291 - KeyF3 Key = 292 - KeyF4 Key = 293 - KeyF5 Key = 294 - KeyF6 Key = 295 - KeyF7 Key = 296 - KeyF8 Key = 297 - KeyF9 Key = 298 - KeyF10 Key = 299 - KeyF11 Key = 300 - KeyF12 Key = 301 - KeyF13 Key = 302 - KeyF14 Key = 303 - KeyF15 Key = 304 - KeyF16 Key = 305 - KeyF17 Key = 306 - KeyF18 Key = 307 - KeyF19 Key = 308 - KeyF20 Key = 309 - KeyF21 Key = 310 - KeyF22 Key = 311 - KeyF23 Key = 312 - KeyF24 Key = 313 - KeyF25 Key = 314 - KeyKP0 Key = 320 - KeyKP1 Key = 321 - KeyKP2 Key = 322 - KeyKP3 Key = 323 - KeyKP4 Key = 324 - KeyKP5 Key = 325 - KeyKP6 Key = 326 - KeyKP7 Key = 327 - KeyKP8 Key = 328 - KeyKP9 Key = 329 - KeyKPDecimal Key = 330 - KeyKPDivide Key = 331 - KeyKPMultiply Key = 332 - KeyKPSubtract Key = 333 - KeyKPAdd Key = 334 - KeyKPEnter Key = 335 - KeyKPEqual Key = 336 - KeyLeftShift Key = 340 - KeyLeftControl Key = 341 - KeyLeftAlt Key = 342 - KeyLeftSuper Key = 343 - KeyRightShift Key = 344 - KeyRightControl Key = 345 - KeyRightAlt Key = 346 - KeyRightSuper Key = 347 - KeyMenu Key = 348 - - KeyLast Key = KeyMenu -) - -type ModifierKey int - -const ( - ModShift ModifierKey = 0x0001 - ModControl ModifierKey = 0x0002 - ModAlt ModifierKey = 0x0004 - ModSuper ModifierKey = 0x0008 - ModCapsLock ModifierKey = 0x0010 - ModNumLock ModifierKey = 0x0020 -) - -type MouseButton int - -const ( - MouseButton1 MouseButton = 0 - MouseButton2 MouseButton = 1 - MouseButton3 MouseButton = 2 - MouseButton4 MouseButton = 3 - MouseButton5 MouseButton = 4 - MouseButton6 MouseButton = 5 - MouseButton7 MouseButton = 6 - MouseButton8 MouseButton = 7 - MouseButtonLast MouseButton = MouseButton8 - MouseButtonLeft MouseButton = MouseButton1 - MouseButtonRight MouseButton = MouseButton2 - MouseButtonMiddle MouseButton = MouseButton3 -) - -var ( - NotInitialized Error = 0x00010001 - NoCurrentContext Error = 0x00010002 - InvalidEnum Error = 0x00010003 - InvalidValue Error = 0x00010004 - OutOfMemory Error = 0x00010005 - ApiUnavailable Error = 0x00010006 - VersionUnavailable Error = 0x00010007 - PlatformError Error = 0x00010008 - FormatUnavailable Error = 0x00010009 - NoWindowContext Error = 0x0001000A -) - -type PeripheralEvent int - -const ( - Connected PeripheralEvent = 0x00040001 - Disconnected PeripheralEvent = 0x00040002 -) - -type StandardCursor int - -const ( - ArrowCursor StandardCursor = 0x00036001 - IBeamCursor StandardCursor = 0x00036002 - CrosshairCursor StandardCursor = 0x00036003 - HandCursor StandardCursor = 0x00036004 - HResizeCursor StandardCursor = 0x00036005 - VResizeCursor StandardCursor = 0x00036006 - - // v3.4 - ResizeNWSECursor StandardCursor = 0x00036007 - ResizeNESWCursor StandardCursor = 0x00036008 - ResizeAllCursor StandardCursor = 0x00036009 - NotAllowedCursor StandardCursor = 0x0003600A -) - -type Error int - -func (e Error) Error() string { - switch e { - case NotInitialized: - return "the GLFW library is not initialized" - case NoCurrentContext: - return "there is no current context" - case InvalidEnum: - return "invalid argument for enum parameter" - case InvalidValue: - return "invalid value for parameter" - case OutOfMemory: - return "out of memory" - case ApiUnavailable: - return "the requested API is unavailable" - case VersionUnavailable: - return "the requested API version is unavailable" - case PlatformError: - return "a platform-specific error occurred" - case FormatUnavailable: - return "the requested format is unavailable" - case NoWindowContext: - return "the specified window has no context" - default: - return "ERROR: UNKNOWN GLFW ERROR" - } -} - -type VidMode struct { - Width int - Height int - RedBits int - GreenBits int - BlueBits int - RefreshRate int -} - -type Image struct { - Width int - Height int - Pixels []byte -} diff --git a/internal/graphicsdriver/opengl/graphics_glfw.go b/internal/graphicsdriver/opengl/graphics_glfw.go index c94f17de8..af3258de0 100644 --- a/internal/graphicsdriver/opengl/graphics_glfw.go +++ b/internal/graphicsdriver/opengl/graphics_glfw.go @@ -22,21 +22,40 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/glfw" ) -func (g *Graphics) SetGLFWClientAPI() { +func (g *Graphics) SetGLFWClientAPI() error { if g.context.ctx.IsES() { - glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLESAPI) - glfw.WindowHint(glfw.ContextVersionMajor, 3) - glfw.WindowHint(glfw.ContextVersionMinor, 0) - glfw.WindowHint(glfw.ContextCreationAPI, glfw.EGLContextAPI) - return + if err := glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLESAPI); err != nil { + return err + } + if err := glfw.WindowHint(glfw.ContextVersionMajor, 3); err != nil { + return err + } + if err := glfw.WindowHint(glfw.ContextVersionMinor, 0); err != nil { + return err + } + if err := glfw.WindowHint(glfw.ContextCreationAPI, glfw.EGLContextAPI); err != nil { + return err + } + return nil } - glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI) - glfw.WindowHint(glfw.ContextVersionMajor, 3) - glfw.WindowHint(glfw.ContextVersionMinor, 2) + if err := glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI); err != nil { + return err + } + if err := glfw.WindowHint(glfw.ContextVersionMajor, 3); err != nil { + return err + } + if err := glfw.WindowHint(glfw.ContextVersionMinor, 2); err != nil { + return err + } // macOS requires forward-compatible and a core profile. if runtime.GOOS == "darwin" { - glfw.WindowHint(glfw.OpenGLForwardCompat, glfw.True) - glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) + if err := glfw.WindowHint(glfw.OpenGLForwardCompat, glfw.True); err != nil { + return err + } + if err := glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile); err != nil { + return err + } } + return nil } diff --git a/internal/ui/input_glfw.go b/internal/ui/input_glfw.go index 9a19c0968..dd60d7720 100644 --- a/internal/ui/input_glfw.go +++ b/internal/ui/input_glfw.go @@ -31,20 +31,27 @@ var glfwMouseButtonToMouseButton = map[glfw.MouseButton]MouseButton{ glfw.MouseButton5: MouseButton4, } -func (u *userInterfaceImpl) registerInputCallbacks() { - u.window.SetCharModsCallback(glfw.ToCharModsCallback(func(w *glfw.Window, char rune, mods glfw.ModifierKey) { +func (u *userInterfaceImpl) registerInputCallbacks() error { + if _, err := u.window.SetCharModsCallback(glfw.ToCharModsCallback(func(w *glfw.Window, char rune, mods glfw.ModifierKey) { // As this function is called from GLFW callbacks, the current thread is main. u.m.Lock() defer u.m.Unlock() u.inputState.appendRune(char) - })) - u.window.SetScrollCallback(glfw.ToScrollCallback(func(w *glfw.Window, xoff float64, yoff float64) { + })); err != nil { + return err + } + + if _, err := u.window.SetScrollCallback(glfw.ToScrollCallback(func(w *glfw.Window, xoff float64, yoff float64) { // As this function is called from GLFW callbacks, the current thread is main. u.m.Lock() defer u.m.Unlock() u.inputState.WheelX += xoff u.inputState.WheelY += yoff - })) + })); err != nil { + return err + } + + return nil } func (u *userInterfaceImpl) updateInputState() error { @@ -61,13 +68,24 @@ func (u *userInterfaceImpl) updateInputStateImpl() error { defer u.m.Unlock() for uk, gk := range uiKeyToGLFWKey { - u.inputState.KeyPressed[uk] = u.window.GetKey(gk) == glfw.Press + s, err := u.window.GetKey(gk) + if err != nil { + return err + } + u.inputState.KeyPressed[uk] = s == glfw.Press } for gb, ub := range glfwMouseButtonToMouseButton { - u.inputState.MouseButtonPressed[ub] = u.window.GetMouseButton(gb) == glfw.Press + s, err := u.window.GetMouseButton(gb) + if err != nil { + return err + } + u.inputState.MouseButtonPressed[ub] = s == glfw.Press } - m := u.currentMonitor() + m, err := u.currentMonitor() + if err != nil { + return err + } s := m.deviceScaleFactor() cx, cy := u.savedCursorX, u.savedCursorY @@ -80,9 +98,14 @@ func (u *userInterfaceImpl) updateInputStateImpl() error { cx2, cy2 := u.context.logicalPositionToClientPosition(cx, cy, s) cx2 = dipToGLFWPixel(cx2, m) cy2 = dipToGLFWPixel(cy2, m) - u.window.SetCursorPos(cx2, cy2) + if err := u.window.SetCursorPos(cx2, cy2); err != nil { + return err + } } else { - cx2, cy2 := u.window.GetCursorPos() + cx2, cy2, err := u.window.GetCursorPos() + if err != nil { + return err + } cx2 = dipFromGLFWPixel(cx2, m) cy2 = dipFromGLFWPixel(cy2, m) cx, cy = u.context.clientPositionToLogicalPosition(cx2, cy2, s) @@ -118,7 +141,12 @@ func (u *userInterfaceImpl) keyName(key Key) string { if u.isTerminated() { return } - name = glfw.GetKeyName(gk, 0) + n, err := glfw.GetKeyName(gk, 0) + if err != nil { + theGlobalState.setError(err) + return + } + name = n }) return name } diff --git a/internal/ui/monitor_glfw.go b/internal/ui/monitor_glfw.go index 247de3759..db5b6786c 100644 --- a/internal/ui/monitor_glfw.go +++ b/internal/ui/monitor_glfw.go @@ -114,11 +114,17 @@ func (m *monitors) monitorFromPosition(x, y int) *Monitor { } // update must be called from the main thread. -func (m *monitors) update() { - glfwMonitors := glfw.GetMonitors() +func (m *monitors) update() error { + glfwMonitors, err := glfw.GetMonitors() + if err != nil { + return err + } newMonitors := make([]*Monitor, 0, len(glfwMonitors)) for i, m := range glfwMonitors { - x, y := m.GetPos() + x, y, err := m.GetPos() + if err != nil { + return err + } // TODO: Detect the update of the content scale by SetContentScaleCallback (#2343). contentScale := 1.0 @@ -138,13 +144,24 @@ func (m *monitors) update() { break } - w, h := glfwMonitorSizeInGLFWPixels(m) + videoMode, err := m.GetVideoMode() + if err != nil { + return err + } + name, err := m.GetName() + if err != nil { + return err + } + w, h, err := glfwMonitorSizeInGLFWPixels(m) + if err != nil { + return err + } b := image.Rect(x, y, x+w, y+h) newMonitors = append(newMonitors, &Monitor{ m: m, - videoMode: m.GetVideoMode(), + videoMode: videoMode, id: i, - name: m.GetName(), + name: name, boundsInGLFWPixels: b, contentScale: contentScale, }) @@ -155,4 +172,5 @@ func (m *monitors) update() { m.m.Unlock() atomic.StoreInt32(&m.updateCalled, 1) + return nil } diff --git a/internal/ui/ui_glfw.go b/internal/ui/ui_glfw.go index 6bc1c8261..4e4aa5f58 100644 --- a/internal/ui/ui_glfw.go +++ b/internal/ui/ui_glfw.go @@ -148,9 +148,13 @@ func init() { if err := initialize(); err != nil { panic(err) } - glfw.SetMonitorCallback(glfw.ToMonitorCallback(func(monitor *glfw.Monitor, event glfw.PeripheralEvent) { - theMonitors.update() - })) + if _, err := glfw.SetMonitorCallback(glfw.ToMonitorCallback(func(monitor *glfw.Monitor, event glfw.PeripheralEvent) { + if err := theMonitors.update(); err != nil { + theGlobalState.setError(err) + } + })); err != nil { + panic(err) + } } var glfwSystemCursors = map[CursorShape]*glfw.Cursor{} @@ -161,7 +165,9 @@ func initialize() error { } // Update the monitor first. The monitor state is depended on various functions like initialMonitorByOS. - theMonitors.update() + if err := theMonitors.update(); err != nil { + return err + } m, err := initialMonitorByOS() if err != nil { @@ -180,15 +186,60 @@ func initialize() error { // Create system cursors. These cursors are destroyed at glfw.Terminate(). glfwSystemCursors[CursorShapeDefault] = nil - glfwSystemCursors[CursorShapeText] = glfw.CreateStandardCursor(glfw.IBeamCursor) - glfwSystemCursors[CursorShapeCrosshair] = glfw.CreateStandardCursor(glfw.CrosshairCursor) - glfwSystemCursors[CursorShapePointer] = glfw.CreateStandardCursor(glfw.HandCursor) - glfwSystemCursors[CursorShapeEWResize] = glfw.CreateStandardCursor(glfw.HResizeCursor) - glfwSystemCursors[CursorShapeNSResize] = glfw.CreateStandardCursor(glfw.VResizeCursor) - glfwSystemCursors[CursorShapeNESWResize] = glfw.CreateStandardCursor(glfw.ResizeNESWCursor) - glfwSystemCursors[CursorShapeNWSEResize] = glfw.CreateStandardCursor(glfw.ResizeNWSECursor) - glfwSystemCursors[CursorShapeMove] = glfw.CreateStandardCursor(glfw.ResizeAllCursor) - glfwSystemCursors[CursorShapeNotAllowed] = glfw.CreateStandardCursor(glfw.NotAllowedCursor) + + c, err := glfw.CreateStandardCursor(glfw.IBeamCursor) + if err != nil { + return err + } + glfwSystemCursors[CursorShapeText] = c + + c, err = glfw.CreateStandardCursor(glfw.CrosshairCursor) + if err != nil { + return err + } + glfwSystemCursors[CursorShapeCrosshair] = c + + c, err = glfw.CreateStandardCursor(glfw.HandCursor) + if err != nil { + return err + } + glfwSystemCursors[CursorShapePointer] = c + + c, err = glfw.CreateStandardCursor(glfw.HResizeCursor) + if err != nil { + return err + } + glfwSystemCursors[CursorShapeEWResize] = c + + c, err = glfw.CreateStandardCursor(glfw.VResizeCursor) + if err != nil { + return err + } + glfwSystemCursors[CursorShapeNSResize] = c + + c, err = glfw.CreateStandardCursor(glfw.ResizeNESWCursor) + if err != nil { + return err + } + glfwSystemCursors[CursorShapeNESWResize] = c + + c, err = glfw.CreateStandardCursor(glfw.ResizeNWSECursor) + if err != nil { + return err + } + glfwSystemCursors[CursorShapeNWSEResize] = c + + c, err = glfw.CreateStandardCursor(glfw.ResizeAllCursor) + if err != nil { + return err + } + glfwSystemCursors[CursorShapeMove] = c + + c, err = glfw.CreateStandardCursor(glfw.NotAllowedCursor) + if err != nil { + return err + } + glfwSystemCursors[CursorShapeNotAllowed] = c return nil } @@ -220,7 +271,12 @@ func (u *userInterfaceImpl) Monitor() *Monitor { if u.isTerminated() { return } - monitor = u.currentMonitor() + m, err := u.currentMonitor() + if err != nil { + theGlobalState.setError(err) + return + } + monitor = m }) return monitor } @@ -246,28 +302,39 @@ func (u *userInterfaceImpl) setTerminated() { } // setWindowMonitor must be called on the main thread. -func (u *userInterfaceImpl) setWindowMonitor(monitor *Monitor) { +func (u *userInterfaceImpl) setWindowMonitor(monitor *Monitor) error { if microsoftgdk.IsXbox() { - return + return nil } // Ignore if it is the same monitor. - if monitor == u.currentMonitor() { - return + m, err := u.currentMonitor() + if err != nil { + return err + } + if monitor == m { + return nil } ww := u.origWindowWidthInDIP wh := u.origWindowHeightInDIP - fullscreen := u.isFullscreen() + fullscreen, err := u.isFullscreen() + if err != nil { + return err + } // This is copied from setFullscreen. They should probably use a shared function. if fullscreen { - u.setFullscreen(false) + if err := u.setFullscreen(false); err != nil { + return err + } // Just after exiting fullscreen, the window state seems very unstable (#2758). // Wait for a while with polling events. if runtime.GOOS == "darwin" { for i := 0; i < 60; i++ { - glfw.PollEvents() + if err := glfw.PollEvents(); err != nil { + return err + } time.Sleep(time.Second / 60) } } @@ -281,14 +348,20 @@ func (u *userInterfaceImpl) setWindowMonitor(monitor *Monitor) { mw = dipToGLFWPixel(mw, monitor) mh = dipToGLFWPixel(mh, monitor) px, py := InitialWindowPosition(int(mw), int(mh), int(w), int(h)) - u.window.SetPos(mx+px, my+py) + if err := u.window.SetPos(mx+px, my+py); err != nil { + return err + } if fullscreen { // Calling setFullscreen immediately might not work well, especially on Linux (#2778). // Just wait a little bit. 1/30[s] seems enough in most cases. time.Sleep(time.Second / 30) - u.setFullscreen(true) + if err := u.setFullscreen(true); err != nil { + return err + } } + + return nil } func (u *userInterfaceImpl) getWindowSizeLimitsInDIP() (minw, minh, maxw, maxh int) { @@ -531,7 +604,11 @@ func (u *userInterfaceImpl) ScreenSizeInFullscreen() (int, int) { if u.isTerminated() { return } - m := u.currentMonitor() + m, err := u.currentMonitor() + if err != nil { + theGlobalState.setError(err) + return + } if m == nil { return } @@ -543,11 +620,15 @@ func (u *userInterfaceImpl) ScreenSizeInFullscreen() (int, int) { } // isFullscreen must be called from the main thread. -func (u *userInterfaceImpl) isFullscreen() bool { +func (u *userInterfaceImpl) isFullscreen() (bool, error) { if !u.isRunning() { panic("ui: isFullscreen can't be called before the main loop starts") } - return u.window.GetMonitor() != nil || u.isNativeFullscreen() + m, err := u.window.GetMonitor() + if err != nil { + return false, err + } + return m != nil || u.isNativeFullscreen(), nil } func (u *userInterfaceImpl) IsFullscreen() bool { @@ -561,14 +642,19 @@ func (u *userInterfaceImpl) IsFullscreen() bool { if !u.isRunning() { return u.isInitFullscreen() } - var b bool + var fullscreen bool u.mainThread.Call(func() { if u.isTerminated() { return } - b = u.isFullscreen() + b, err := u.isFullscreen() + if err != nil { + theGlobalState.setError(err) + return + } + fullscreen = b }) - return b + return fullscreen } func (u *userInterfaceImpl) SetFullscreen(fullscreen bool) { @@ -588,10 +674,18 @@ func (u *userInterfaceImpl) SetFullscreen(fullscreen bool) { if u.isTerminated() { return } - if u.isFullscreen() == fullscreen { + f, err := u.isFullscreen() + if err != nil { + theGlobalState.setError(err) + return + } + if f == fullscreen { + return + } + if err := u.setFullscreen(fullscreen); err != nil { + theGlobalState.setError(err) return } - u.setFullscreen(fullscreen) }) } @@ -605,7 +699,12 @@ func (u *userInterfaceImpl) IsFocused() bool { if u.isTerminated() { return } - focused = u.window.GetAttrib(glfw.Focused) == glfw.True + a, err := u.window.GetAttrib(glfw.Focused) + if err != nil { + theGlobalState.setError(err) + return + } + focused = a == glfw.True }) return focused } @@ -628,6 +727,7 @@ func (u *userInterfaceImpl) SetFPSMode(mode FPSModeType) { u.m.Unlock() return } + u.mainThread.Call(func() { if u.isTerminated() { return @@ -636,7 +736,10 @@ func (u *userInterfaceImpl) SetFPSMode(mode FPSModeType) { u.fpsMode = mode return } - u.setFPSMode(mode) + if err := u.setFPSMode(mode); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -646,7 +749,10 @@ func (u *userInterfaceImpl) ScheduleFrame() { } // As the main thread can be blocked, do not check the current FPS mode. // PostEmptyEvent is concurrent safe. - glfw.PostEmptyEvent() + if err := glfw.PostEmptyEvent(); err != nil { + theGlobalState.setError(err) + return + } } func (u *userInterfaceImpl) CursorMode() CursorMode { @@ -662,7 +768,12 @@ func (u *userInterfaceImpl) CursorMode() CursorMode { if u.isTerminated() { return } - mode = u.window.GetInputMode(glfw.CursorMode) + m, err := u.window.GetInputMode(glfw.CursorMode) + if err != nil { + theGlobalState.setError(err) + return + } + mode = m }) var v CursorMode @@ -691,9 +802,15 @@ func (u *userInterfaceImpl) SetCursorMode(mode CursorMode) { if u.isTerminated() { return } - u.window.SetInputMode(glfw.CursorMode, driverCursorModeToGLFWCursorMode(mode)) + if err := u.window.SetInputMode(glfw.CursorMode, driverCursorModeToGLFWCursorMode(mode)); err != nil { + theGlobalState.setError(err) + return + } if mode == CursorModeVisible { - u.window.SetCursor(glfwSystemCursors[u.getCursorShape()]) + if err := u.window.SetCursor(glfwSystemCursors[u.getCursorShape()]); err != nil { + theGlobalState.setError(err) + return + } } }) } @@ -718,7 +835,10 @@ func (u *userInterfaceImpl) SetCursorShape(shape CursorShape) { if u.isTerminated() { return } - u.window.SetCursor(glfwSystemCursors[shape]) + if err := u.window.SetCursor(glfwSystemCursors[shape]); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -735,7 +855,12 @@ func (u *userInterfaceImpl) DeviceScaleFactor() float64 { if u.isTerminated() { return } - f = u.currentMonitor().deviceScaleFactor() + m, err := u.currentMonitor() + if err != nil { + theGlobalState.setError(err) + return + } + f = m.deviceScaleFactor() }) return f } @@ -779,23 +904,39 @@ func (u *userInterfaceImpl) createWindow() error { if wy < 0 { wy = 0 } - u.setWindowPositionInDIP(wx, wy, monitor) + if err := u.setWindowPositionInDIP(wx, wy, monitor); err != nil { + return err + } // Though the size is already specified, call setWindowSizeInDIP explicitly to adjust member variables. - u.setWindowSizeInDIP(ww, wh, true) + if err := u.setWindowSizeInDIP(ww, wh, true); err != nil { + return err + } - initializeWindowAfterCreation(window) + if err := initializeWindowAfterCreation(window); err != nil { + return err + } // Even just after a window creation, FramebufferSize callback might be invoked (#1847). // Ensure to consume this callback. - u.waitForFramebufferSizeCallback(u.window, nil) + if err := u.waitForFramebufferSizeCallback(u.window, nil); err != nil { + return err + } - u.window.SetInputMode(glfw.CursorMode, driverCursorModeToGLFWCursorMode(u.getInitCursorMode())) - u.window.SetCursor(glfwSystemCursors[u.getCursorShape()]) - u.window.SetTitle(u.title) + if err := u.window.SetInputMode(glfw.CursorMode, driverCursorModeToGLFWCursorMode(u.getInitCursorMode())); err != nil { + return err + } + if err := u.window.SetCursor(glfwSystemCursors[u.getCursorShape()]); err != nil { + return err + } + if err := u.window.SetTitle(u.title); err != nil { + return err + } // Icons are set after every frame. They don't have to be cared here. - u.updateWindowSizeLimits() + if err := u.updateWindowSizeLimits(); err != nil { + return err + } return nil } @@ -807,7 +948,7 @@ func (u *userInterfaceImpl) endFrame() { } // registerWindowCloseCallback must be called from the main thread. -func (u *userInterfaceImpl) registerWindowCloseCallback() { +func (u *userInterfaceImpl) registerWindowCloseCallback() error { if u.closeCallback == nil { u.closeCallback = glfw.ToCloseCallback(func(_ *glfw.Window) { u.m.Lock() @@ -817,15 +958,24 @@ func (u *userInterfaceImpl) registerWindowCloseCallback() { if !u.isWindowClosingHandled() { return } - u.window.Focus() - u.window.SetShouldClose(false) + if err := u.window.Focus(); err != nil { + theGlobalState.setError(err) + return + } + if err := u.window.SetShouldClose(false); err != nil { + theGlobalState.setError(err) + return + } }) } - u.window.SetCloseCallback(u.closeCallback) + if _, err := u.window.SetCloseCallback(u.closeCallback); err != nil { + return err + } + return nil } // registerWindowFramebufferSizeCallback must be called from the main thread. -func (u *userInterfaceImpl) registerWindowFramebufferSizeCallback() { +func (u *userInterfaceImpl) registerWindowFramebufferSizeCallback() error { if u.defaultFramebufferSizeCallback == nil && runtime.GOOS != "darwin" { // When the window gets resized (either by manual window resize or a window // manager), glfw sends a framebuffer size callback which we need to handle (#1960). @@ -834,25 +984,46 @@ func (u *userInterfaceImpl) registerWindowFramebufferSizeCallback() { // When a decorating state changes, the callback of arguments might be an unexpected value on macOS (#2257) // Then, do not register this callback on macOS. u.defaultFramebufferSizeCallback = glfw.ToFramebufferSizeCallback(func(_ *glfw.Window, w, h int) { - if u.isFullscreen() { + f, err := u.isFullscreen() + if err != nil { + theGlobalState.setError(err) return } - if u.window.GetAttrib(glfw.Iconified) == glfw.True { + if f { + return + } + a, err := u.window.GetAttrib(glfw.Iconified) + if err != nil { + theGlobalState.setError(err) + return + } + if a == glfw.True { return } // The framebuffer size is always scaled by the device scale factor (#1975). // See also the implementation in uiContext.updateOffscreen. - s := u.currentMonitor().deviceScaleFactor() + m, err := u.currentMonitor() + if err != nil { + theGlobalState.setError(err) + return + } + s := m.deviceScaleFactor() ww := int(float64(w) / s) wh := int(float64(h) / s) - u.setWindowSizeInDIP(ww, wh, false) + if err := u.setWindowSizeInDIP(ww, wh, false); err != nil { + theGlobalState.setError(err) + return + } }) } - u.window.SetFramebufferSizeCallback(u.defaultFramebufferSizeCallback) + if _, err := u.window.SetFramebufferSizeCallback(u.defaultFramebufferSizeCallback); err != nil { + return err + } + return nil } -func (u *userInterfaceImpl) registerDropCallback() { +func (u *userInterfaceImpl) registerDropCallback() error { if u.dropCallback == nil { u.dropCallback = glfw.ToDropCallback(func(_ *glfw.Window, names []string) { u.m.Lock() @@ -860,7 +1031,10 @@ func (u *userInterfaceImpl) registerDropCallback() { u.inputState.DroppedFiles = file.NewVirtualFS(names) }) } - u.window.SetDropCallback(u.dropCallback) + if _, err := u.window.SetDropCallback(u.dropCallback); err != nil { + return err + } + return nil } // waitForFramebufferSizeCallback waits for GLFW's FramebufferSize callback. @@ -868,7 +1042,7 @@ func (u *userInterfaceImpl) registerDropCallback() { // If the callback is not invoked for a while, waitForFramebufferSizeCallback times out and return. // // waitForFramebufferSizeCallback must be called from the main thread. -func (u *userInterfaceImpl) waitForFramebufferSizeCallback(window *glfw.Window, f func()) { +func (u *userInterfaceImpl) waitForFramebufferSizeCallback(window *glfw.Window, f func() error) error { u.framebufferSizeCallbackCh = make(chan struct{}, 1) if u.framebufferSizeCallback == nil { @@ -881,10 +1055,14 @@ func (u *userInterfaceImpl) waitForFramebufferSizeCallback(window *glfw.Window, } }) } - window.SetFramebufferSizeCallback(u.framebufferSizeCallback) + if _, err := window.SetFramebufferSizeCallback(u.framebufferSizeCallback); err != nil { + return err + } if f != nil { - f() + if err := f(); err != nil { + return err + } } // Use the timeout as FramebufferSize event might not be fired (#1618). @@ -893,7 +1071,9 @@ func (u *userInterfaceImpl) waitForFramebufferSizeCallback(window *glfw.Window, event: for { - glfw.PollEvents() + if err := glfw.PollEvents(); err != nil { + return err + } select { case <-u.framebufferSizeCallbackCh: break event @@ -903,14 +1083,20 @@ event: time.Sleep(time.Millisecond) } } - window.SetFramebufferSizeCallback(u.defaultFramebufferSizeCallback) + if _, err := window.SetFramebufferSizeCallback(u.defaultFramebufferSizeCallback); err != nil { + return err + } close(u.framebufferSizeCallbackCh) u.framebufferSizeCallbackCh = nil + + return nil } func (u *userInterfaceImpl) initOnMainThread(options *RunOptions) error { - glfw.WindowHint(glfw.AutoIconify, glfw.False) + if err := glfw.WindowHint(glfw.AutoIconify, glfw.False); err != nil { + return err + } // On macOS, window decoration should be initialized once after buffers are swapped (#2600). if runtime.GOOS != "darwin" { @@ -918,14 +1104,18 @@ func (u *userInterfaceImpl) initOnMainThread(options *RunOptions) error { if u.isInitWindowDecorated() { decorated = glfw.True } - glfw.WindowHint(glfw.Decorated, decorated) + if err := glfw.WindowHint(glfw.Decorated, decorated); err != nil { + return err + } } glfwTransparent := glfw.False if options.ScreenTransparent { glfwTransparent = glfw.True } - glfw.WindowHint(glfw.TransparentFramebuffer, glfwTransparent) + if err := glfw.WindowHint(glfw.TransparentFramebuffer, glfwTransparent); err != nil { + return err + } g, err := newGraphicsDriver(&graphicsDriverCreatorImpl{ transparent: options.ScreenTransparent, @@ -937,9 +1127,13 @@ func (u *userInterfaceImpl) initOnMainThread(options *RunOptions) error { u.graphicsDriver.SetTransparent(options.ScreenTransparent) if u.graphicsDriver.IsGL() { - u.graphicsDriver.(interface{ SetGLFWClientAPI() }).SetGLFWClientAPI() + if err := u.graphicsDriver.(interface{ SetGLFWClientAPI() error }).SetGLFWClientAPI(); err != nil { + return err + } } else { - glfw.WindowHint(glfw.ClientAPI, glfw.NoAPI) + if err := glfw.WindowHint(glfw.ClientAPI, glfw.NoAPI); err != nil { + return err + } } // Before creating a window, set it unresizable no matter what u.isInitWindowResizable() is (#1987). @@ -948,29 +1142,39 @@ func (u *userInterfaceImpl) initOnMainThread(options *RunOptions) error { if u.windowResizingMode == WindowResizingModeEnabled { resizable = glfw.True } - glfw.WindowHint(glfw.Resizable, resizable) + if err := glfw.WindowHint(glfw.Resizable, resizable); err != nil { + return err + } floating := glfw.False if u.isInitWindowFloating() { floating = glfw.True } - glfw.WindowHint(glfw.Floating, floating) + if err := glfw.WindowHint(glfw.Floating, floating); err != nil { + return err + } focused := glfw.True if options.InitUnfocused { focused = glfw.False } - glfw.WindowHint(glfw.FocusOnShow, focused) + if err := glfw.WindowHint(glfw.FocusOnShow, focused); err != nil { + return err + } mousePassthrough := glfw.False if u.isInitWindowMousePassthrough() { mousePassthrough = glfw.True } - glfw.WindowHint(glfw.MousePassthrough, mousePassthrough) + if err := glfw.WindowHint(glfw.MousePassthrough, mousePassthrough); err != nil { + return err + } // Set the window visible explicitly or the application freezes on Wayland (#974). if os.Getenv("WAYLAND_DISPLAY") != "" { - glfw.WindowHint(glfw.Visible, glfw.True) + if err := glfw.WindowHint(glfw.Visible, glfw.True); err != nil { + return err + } } if err := u.createWindow(); err != nil { @@ -979,7 +1183,9 @@ func (u *userInterfaceImpl) initOnMainThread(options *RunOptions) error { // Maximizing a window requires a proper size and position. Call Maximize here (#1117). if u.isInitWindowMaximized() { - u.window.Maximize() + if err := u.window.Maximize(); err != nil { + return err + } } u.setWindowResizingModeForOS(u.windowResizingMode) @@ -991,67 +1197,110 @@ func (u *userInterfaceImpl) initOnMainThread(options *RunOptions) error { // On macOS, the window is shown once after buffers are swapped at update. if runtime.GOOS != "darwin" { - u.window.Show() + if err := u.window.Show(); err != nil { + return err + } } if g, ok := u.graphicsDriver.(interface{ SetWindow(uintptr) }); ok { - g.SetWindow(u.nativeWindow()) + w, err := u.nativeWindow() + if err != nil { + return err + } + g.SetWindow(w) } - gamepad.SetNativeWindow(u.nativeWindow()) + w, err := u.nativeWindow() + if err != nil { + return err + } + gamepad.SetNativeWindow(w) // Register callbacks after the window initialization done. // The callback might cause swapping frames, that assumes the window is already set (#2137). - u.registerWindowCloseCallback() - u.registerWindowFramebufferSizeCallback() - u.registerInputCallbacks() - u.registerDropCallback() + if err := u.registerWindowCloseCallback(); err != nil { + return err + } + if err := u.registerWindowFramebufferSizeCallback(); err != nil { + return err + } + if err := u.registerInputCallbacks(); err != nil { + return err + } + if err := u.registerDropCallback(); err != nil { + return err + } return nil } -func (u *userInterfaceImpl) outsideSize() (float64, float64) { - if u.isFullscreen() && !u.isNativeFullscreen() { +func (u *userInterfaceImpl) outsideSize() (float64, float64, error) { + f, err := u.isFullscreen() + if err != nil { + return 0, 0, err + } + if f && !u.isNativeFullscreen() { // On Linux, the window size is not reliable just after making the window // fullscreened. Use the monitor size. // On macOS's native fullscreen, the window's size returns a more precise size // reflecting the adjustment of the view size (#1745). var w, h float64 - if m := u.currentMonitor(); m != nil { + m, err := u.currentMonitor() + if err != nil { + return 0, 0, err + } + if m != nil { w, h = m.sizeInDIP() } - return w, h + return w, h, nil } - if u.window.GetAttrib(glfw.Iconified) == glfw.True { - return float64(u.origWindowWidthInDIP), float64(u.origWindowHeightInDIP) + a, err := u.window.GetAttrib(glfw.Iconified) + if err != nil { + return 0, 0, err + } + if a == glfw.True { + return float64(u.origWindowWidthInDIP), float64(u.origWindowHeightInDIP), nil } // Instead of u.origWindow{Width,Height}InDIP, use the actual window size here. // On Windows, the specified size at SetSize and the actual window size might // not match (#1163). - ww, wh := u.window.GetSize() - w := dipFromGLFWPixel(float64(ww), u.currentMonitor()) - h := dipFromGLFWPixel(float64(wh), u.currentMonitor()) - return w, h + ww, wh, err := u.window.GetSize() + if err != nil { + return 0, 0, err + } + m, err := u.currentMonitor() + if err != nil { + return 0, 0, err + } + w := dipFromGLFWPixel(float64(ww), m) + h := dipFromGLFWPixel(float64(wh), m) + return w, h, nil } // setFPSMode must be called from the main thread. -func (u *userInterfaceImpl) setFPSMode(fpsMode FPSModeType) { +func (u *userInterfaceImpl) setFPSMode(fpsMode FPSModeType) error { needUpdate := u.fpsMode != fpsMode || !u.fpsModeInited u.fpsMode = fpsMode u.fpsModeInited = true if !needUpdate { - return + return nil } sticky := glfw.True if fpsMode == FPSModeVsyncOffMinimum { sticky = glfw.False } - u.window.SetInputMode(glfw.StickyMouseButtonsMode, sticky) - u.window.SetInputMode(glfw.StickyKeysMode, sticky) + if err := u.window.SetInputMode(glfw.StickyMouseButtonsMode, sticky); err != nil { + return err + } + if err := u.window.SetInputMode(glfw.StickyKeysMode, sticky); err != nil { + return err + } + + return nil } // update must be called from the main thread. @@ -1060,74 +1309,112 @@ func (u *userInterfaceImpl) update() (float64, float64, error) { return 0, 0, err } - if u.window.ShouldClose() { + sc, err := u.window.ShouldClose() + if err != nil { + return 0, 0, err + } + if sc { return 0, 0, RegularTermination } // On macOS, one swapping buffers seems required before entering fullscreen (#2599). if u.isInitFullscreen() && (u.bufferOnceSwapped || runtime.GOOS != "darwin") { - u.setFullscreen(true) + if err := u.setFullscreen(true); err != nil { + return 0, 0, err + } u.setInitFullscreen(false) } if runtime.GOOS == "darwin" && u.bufferOnceSwapped { + var err error u.darwinInitOnce.Do(func() { // On macOS, window decoration should be initialized once after buffers are swapped (#2600). decorated := glfw.False if u.isInitWindowDecorated() { decorated = glfw.True } - u.window.SetAttrib(glfw.Decorated, decorated) + if err = u.window.SetAttrib(glfw.Decorated, decorated); err != nil { + return + } // The window is not shown at the initialization on macOS. Show the window here. - u.window.Show() + if err = u.window.Show(); err != nil { + return + } }) + if err != nil { + return 0, 0, err + } } // Initialize vsync after SetMonitor is called. See the comment in updateVsync. // Calling this inside setWindowSize didn't work (#1363). if !u.fpsModeInited { - u.setFPSMode(u.fpsMode) + if err := u.setFPSMode(u.fpsMode); err != nil { + return 0, 0, err + } } if u.fpsMode != FPSModeVsyncOffMinimum { // TODO: Updating the input can be skipped when clock.Update returns 0 (#1367). - glfw.PollEvents() + if err := glfw.PollEvents(); err != nil { + return 0, 0, err + } } else { - glfw.WaitEvents() + if err := glfw.WaitEvents(); err != nil { + return 0, 0, err + } } // In the initial state on macOS, the window is not shown (#2620). - for u.window.GetAttrib(glfw.Visible) != 0 && !u.isRunnableOnUnfocused() && u.window.GetAttrib(glfw.Focused) == 0 && !u.window.ShouldClose() { + visible, err := u.window.GetAttrib(glfw.Visible) + if err != nil { + return 0, 0, err + } + focused, err := u.window.GetAttrib(glfw.Focused) + if err != nil { + return 0, 0, err + } + shouldClose, err := u.window.ShouldClose() + if err != nil { + return 0, 0, err + } + for visible != 0 && !u.isRunnableOnUnfocused() && focused == 0 && !shouldClose { if err := hooks.SuspendAudio(); err != nil { return 0, 0, err } // Wait for an arbitrary period to avoid busy loop. time.Sleep(time.Second / 60) - glfw.PollEvents() + if err := glfw.PollEvents(); err != nil { + return 0, 0, err + } } if err := hooks.ResumeAudio(); err != nil { return 0, 0, err } - outsideWidth, outsideHeight := u.outsideSize() - return outsideWidth, outsideHeight, nil + return u.outsideSize() } -func (u *userInterfaceImpl) loopGame() error { +func (u *userInterfaceImpl) loopGame() (ferr error) { defer func() { // Post a task to the render thread to ensure all the queued functions are executed. // glfw.Terminate will remove the context and any graphics calls after that will be invalidated. u.renderThread.Call(func() {}) u.mainThread.Call(func() { - glfw.Terminate() + if err := glfw.Terminate(); err != nil { + ferr = err + } u.setTerminated() }) }() u.renderThread.Call(func() { if u.graphicsDriver.IsGL() { - u.window.MakeContextCurrent() + if err := u.window.MakeContextCurrent(); err != nil { + theGlobalState.setError(err) + return + } } }) @@ -1145,7 +1432,11 @@ func (u *userInterfaceImpl) updateGame() error { // On Windows, even if a window is in another workspace, vsync seems to work. // Then let's assume the window is always 'focused' as a workaround. if runtime.GOOS != "windows" { - unfocused = u.window.GetAttrib(glfw.Focused) == glfw.False + a, err := u.window.GetAttrib(glfw.Focused) + if err != nil { + return err + } + unfocused = a == glfw.False } var t1, t2 time.Time @@ -1159,7 +1450,14 @@ func (u *userInterfaceImpl) updateGame() error { var err error if u.mainThread.Call(func() { outsideWidth, outsideHeight, err = u.update() - deviceScaleFactor = u.currentMonitor().deviceScaleFactor() + if err != nil { + return + } + m, err := u.currentMonitor() + if err != nil { + return + } + deviceScaleFactor = m.deviceScaleFactor() }); err != nil { return err } @@ -1167,10 +1465,16 @@ func (u *userInterfaceImpl) updateGame() error { if err := u.context.updateFrame(u.graphicsDriver, outsideWidth, outsideHeight, deviceScaleFactor, u, func() { // Call updateVsync even though fpsMode is not updated. // When toggling to fullscreen, vsync state might be reset unexpectedly (#1787). - u.updateVsyncOnRenderThread() + if err := u.updateVsyncOnRenderThread(); err != nil { + theGlobalState.setError(err) + return + } // This works only for OpenGL. - u.swapBuffersOnRenderThread() + if err := u.swapBuffersOnRenderThread(); err != nil { + theGlobalState.setError(err) + return + } }); err != nil { return err } @@ -1200,7 +1504,11 @@ func (u *userInterfaceImpl) updateGame() error { func (u *userInterfaceImpl) updateIconIfNeeded() error { // In the fullscreen mode, SetIcon fails (#1578). - if u.isFullscreen() { + f, err := u.isFullscreen() + if err != nil { + return err + } + if f { return nil } @@ -1237,26 +1545,39 @@ func (u *userInterfaceImpl) updateIconIfNeeded() error { } u.mainThread.Call(func() { - u.window.SetIcon(newImgs) + err = u.window.SetIcon(newImgs) }) + if err != nil { + return err + } return nil } -func (u *userInterfaceImpl) swapBuffersOnRenderThread() { +func (u *userInterfaceImpl) swapBuffersOnRenderThread() error { if u.graphicsDriver.IsGL() { - u.window.SwapBuffers() + if err := u.window.SwapBuffers(); err != nil { + return err + } } + return nil } // updateWindowSizeLimits must be called from the main thread. -func (u *userInterfaceImpl) updateWindowSizeLimits() { - m := u.currentMonitor() +func (u *userInterfaceImpl) updateWindowSizeLimits() error { + m, err := u.currentMonitor() + if err != nil { + return err + } minw, minh, maxw, maxh := u.getWindowSizeLimitsInDIP() if minw < 0 { // Always set the minimum window width. - minw = int(dipToGLFWPixel(float64(u.minimumWindowWidth()), m)) + mw, err := u.minimumWindowWidth() + if err != nil { + return err + } + minw = int(dipToGLFWPixel(float64(mw), m)) } else { minw = int(dipToGLFWPixel(float64(minw), m)) } @@ -1275,18 +1596,22 @@ func (u *userInterfaceImpl) updateWindowSizeLimits() { } else { maxh = int(dipToGLFWPixel(float64(maxh), m)) } - u.window.SetSizeLimits(minw, minh, maxw, maxh) + if err := u.window.SetSizeLimits(minw, minh, maxw, maxh); err != nil { + return err + } // The window size limit affects the resizing mode, especially on macOS (#). u.setWindowResizingModeForOS(u.windowResizingMode) + + return nil } // disableWindowSizeLimits disables a window size limitation temporarily, especially for fullscreen // In order to enable the size limitation, call updateWindowSizeLimits. // // disableWindowSizeLimits must be called from the main thread. -func (u *userInterfaceImpl) disableWindowSizeLimits() { - u.window.SetSizeLimits(glfw.DontCare, glfw.DontCare, glfw.DontCare, glfw.DontCare) +func (u *userInterfaceImpl) disableWindowSizeLimits() error { + return u.window.SetSizeLimits(glfw.DontCare, glfw.DontCare, glfw.DontCare, glfw.DontCare) } // adjustWindowSizeBasedOnSizeLimitsInDIP adjust the size based on the window size limits. @@ -1309,116 +1634,186 @@ func (u *userInterfaceImpl) adjustWindowSizeBasedOnSizeLimitsInDIP(width, height } // setWindowSize must be called from the main thread. -func (u *userInterfaceImpl) setWindowSizeInDIP(width, height int, callSetSize bool) { +func (u *userInterfaceImpl) setWindowSizeInDIP(width, height int, callSetSize bool) error { if microsoftgdk.IsXbox() { // Do nothing. The size is always fixed. - return + return nil } width, height = u.adjustWindowSizeBasedOnSizeLimitsInDIP(width, height) - if m := u.minimumWindowWidth(); width < m { + m, err := u.minimumWindowWidth() + if err != nil { + return err + } + if width < m { width = m } if height < 1 { height = 1 } - scale := u.currentMonitor().deviceScaleFactor() + mon, err := u.currentMonitor() + if err != nil { + return err + } + scale := mon.deviceScaleFactor() if u.origWindowWidthInDIP == width && u.origWindowHeightInDIP == height && u.lastDeviceScaleFactor == scale { - return + return nil } u.lastDeviceScaleFactor = scale u.origWindowWidthInDIP = width u.origWindowHeightInDIP = height - if !u.isFullscreen() && callSetSize { + f, err := u.isFullscreen() + if err != nil { + return err + } + if !f && callSetSize { // Set the window size after the position. The order matters. // In the opposite order, the window size might not be correct when going back from fullscreen with multi monitors. - oldW, oldH := u.window.GetSize() - newW := int(dipToGLFWPixel(float64(width), u.currentMonitor())) - newH := int(dipToGLFWPixel(float64(height), u.currentMonitor())) + oldW, oldH, err := u.window.GetSize() + if err != nil { + return err + } + m, err := u.currentMonitor() + if err != nil { + return err + } + newW := int(dipToGLFWPixel(float64(width), m)) + newH := int(dipToGLFWPixel(float64(height), m)) if oldW != newW || oldH != newH { // Just after SetSize, GetSize is not reliable especially on Linux/UNIX. // Let's wait for FramebufferSize callback in any cases. - u.waitForFramebufferSizeCallback(u.window, func() { - u.window.SetSize(newW, newH) - }) + if err := u.waitForFramebufferSizeCallback(u.window, func() error { + return u.window.SetSize(newW, newH) + }); err != nil { + return err + } } } - u.updateWindowSizeLimits() + if err := u.updateWindowSizeLimits(); err != nil { + return err + } + return nil } // setOrigWindowPosWithCurrentPos must be called from the main thread. -func (u *userInterfaceImpl) setOrigWindowPosWithCurrentPos() { +func (u *userInterfaceImpl) setOrigWindowPosWithCurrentPos() error { if x, y := u.origWindowPos(); x == invalidPos || y == invalidPos { - u.setOrigWindowPos(u.window.GetPos()) + x, y, err := u.window.GetPos() + if err != nil { + return err + } + u.setOrigWindowPos(x, y) } + return nil } // setFullscreen must be called from the main thread. -func (u *userInterfaceImpl) setFullscreen(fullscreen bool) { - if u.isFullscreen() == fullscreen { - return +func (u *userInterfaceImpl) setFullscreen(fullscreen bool) error { + f, err := u.isFullscreen() + if err != nil { + return err + } + if f == fullscreen { + return nil } - if u.window.GetInputMode(glfw.CursorMode) == glfw.CursorDisabled { + im, err := u.window.GetInputMode(glfw.CursorMode) + if err != nil { + return err + } + if im == glfw.CursorDisabled { u.saveCursorPosition() } // Enter the fullscreen. if fullscreen { - u.disableWindowSizeLimits() + if err := u.disableWindowSizeLimits(); err != nil { + return err + } if x, y := u.origWindowPos(); x == invalidPos || y == invalidPos { - u.setOrigWindowPos(u.window.GetPos()) + x, y, err := u.window.GetPos() + if err != nil { + return err + } + u.setOrigWindowPos(x, y) } if u.isNativeFullscreenAvailable() { u.setNativeFullscreen(fullscreen) } else { - m := u.currentMonitor() + m, err := u.currentMonitor() + if err != nil { + return err + } if m == nil { - return + return nil } vm := m.videoMode - u.window.SetMonitor(m.m, 0, 0, vm.Width, vm.Height, vm.RefreshRate) + if err := u.window.SetMonitor(m.m, 0, 0, vm.Width, vm.Height, vm.RefreshRate); err != nil { + return err + } } u.adjustViewSizeAfterFullscreen() - return + return nil } // Exit the fullscreen. - u.updateWindowSizeLimits() + if err := u.updateWindowSizeLimits(); err != nil { + return err + } // Get the original window position and size before changing the state of fullscreen. // TODO: Why? origX, origY := u.origWindowPos() - ww := int(dipToGLFWPixel(float64(u.origWindowWidthInDIP), u.currentMonitor())) - wh := int(dipToGLFWPixel(float64(u.origWindowHeightInDIP), u.currentMonitor())) + m, err := u.currentMonitor() + if err != nil { + return err + } + ww := int(dipToGLFWPixel(float64(u.origWindowWidthInDIP), m)) + wh := int(dipToGLFWPixel(float64(u.origWindowHeightInDIP), m)) if u.isNativeFullscreenAvailable() { u.setNativeFullscreen(false) // Adjust the window size later (after adjusting the position). - } else if !u.isNativeFullscreenAvailable() && u.window.GetMonitor() != nil { - u.window.SetMonitor(nil, 0, 0, ww, wh, 0) + } else { + m, err := u.window.GetMonitor() + if err != nil { + return err + } + if !u.isNativeFullscreenAvailable() && m != nil { + if err := u.window.SetMonitor(nil, 0, 0, ww, wh, 0); err != nil { + return err + } + } } // glfw.PollEvents is necessary for macOS to enable (*glfw.Window).SetPos and SetSize (#2296). // This polling causes issues on Linux and Windows when rapidly toggling fullscreen, so we only run it under macOS. if runtime.GOOS == "darwin" { - glfw.PollEvents() + if err := glfw.PollEvents(); err != nil { + return err + } } if origX != invalidPos && origY != invalidPos { - u.window.SetPos(origX, origY) + if err := u.window.SetPos(origX, origY); err != nil { + return err + } // Dirty hack for macOS (#703). Rendering doesn't work correctly with one SetPos, but // work with two or more SetPos. if runtime.GOOS == "darwin" { - u.window.SetPos(origX+1, origY) - u.window.SetPos(origX, origY) + if err := u.window.SetPos(origX+1, origY); err != nil { + return err + } + if err := u.window.SetPos(origX, origY); err != nil { + return err + } } u.setOrigWindowPos(invalidPos, invalidPos) } @@ -1426,28 +1821,36 @@ func (u *userInterfaceImpl) setFullscreen(fullscreen bool) { if u.isNativeFullscreenAvailable() { // Set the window size after the position. The order matters. // In the opposite order, the window size might not be correct when going back from fullscreen with multi monitors. - u.window.SetSize(ww, wh) + if err := u.window.SetSize(ww, wh); err != nil { + return err + } } + + return nil } -func (u *userInterfaceImpl) minimumWindowWidth() int { - if u.window.GetAttrib(glfw.Decorated) == glfw.False { - return 1 +func (u *userInterfaceImpl) minimumWindowWidth() (int, error) { + a, err := u.window.GetAttrib(glfw.Decorated) + if err != nil { + return 0, err + } + if a == glfw.False { + return 1, nil } // On Windows, giving a too small width doesn't call a callback (#165). // To prevent hanging up, return asap if the width is too small. // 126 is an arbitrary number and I guess this is small enough . if runtime.GOOS == "windows" { - return 126 + return 126, nil } // On macOS, resizing the window by cursor sometimes ignores the minimum size. // To avoid the flaky behavior, do not add a limitation. - return 1 + return 1, nil } -func (u *userInterfaceImpl) updateVsyncOnRenderThread() { +func (u *userInterfaceImpl) updateVsyncOnRenderThread() error { if u.graphicsDriver.IsGL() { // SwapInterval is affected by the current monitor of the window. // This needs to be called at least after SetMonitor. @@ -1457,41 +1860,57 @@ func (u *userInterfaceImpl) updateVsyncOnRenderThread() { // but is this correct? If glfw.SwapInterval(0) and the driver doesn't support triple // buffering, what will happen? if u.fpsMode == FPSModeVsyncOn { - glfw.SwapInterval(1) + if err := glfw.SwapInterval(1); err != nil { + return err + } } else { - glfw.SwapInterval(0) + if err := glfw.SwapInterval(0); err != nil { + return err + } } } u.graphicsDriver.SetVsyncEnabled(u.fpsMode == FPSModeVsyncOn) + return nil } // currentMonitor returns the current active monitor. // // currentMonitor must be called on the main thread. -func (u *userInterfaceImpl) currentMonitor() *Monitor { +func (u *userInterfaceImpl) currentMonitor() (*Monitor, error) { if u.window == nil { - return u.getInitMonitor() + return u.getInitMonitor(), nil } // Getting a monitor from a window position is not reliable in general (e.g., when a window is put across // multiple monitors, or, before SetWindowPosition is called.). // Get the monitor which the current window belongs to. This requires OS API. - if m := monitorFromWindowByOS(u.window); m != nil { - return m + m, err := monitorFromWindowByOS(u.window) + if err != nil { + return nil, err + } + if m != nil { + return m, nil } // As the fallback, detect the monitor from the window. - x, y := u.window.GetPos() + x, y, err := u.window.GetPos() + if err != nil { + return nil, err + } // On fullscreen, shift the position slightly. Otherwise, a wrong monitor could be detected, as the position is on the edge (#2794). - if u.isFullscreen() { + f, err := u.isFullscreen() + if err != nil { + return nil, err + } + if f { x++ y++ } if m := theMonitors.monitorFromPosition(x, y); m != nil { - return m + return m, nil } - return theMonitors.primaryMonitor() + return theMonitors.primaryMonitor(), nil } func (u *userInterfaceImpl) readInputState(inputState *InputState) { @@ -1512,92 +1931,149 @@ func (u *userInterfaceImpl) Window() Window { // disable the callback temporarily. // maximizeWindow must be called from the main thread. -func (u *userInterfaceImpl) maximizeWindow() { +func (u *userInterfaceImpl) maximizeWindow() error { if u.isNativeFullscreen() { - return + return nil } - if u.isFullscreen() { - return + f, err := u.isFullscreen() + if err != nil { + return err + } + if f { + return nil } - u.window.Maximize() + if err := u.window.Maximize(); err != nil { + return err + } // On Linux/UNIX, maximizing might not finish even though Maximize returns. Just wait for its finish. // Do not check this in the fullscreen since apparently the condition can never be true. - for u.window.GetAttrib(glfw.Maximized) != glfw.True { - glfw.PollEvents() + for { + a, err := u.window.GetAttrib(glfw.Maximized) + if err != nil { + return err + } + if a == glfw.True { + break + } + if err := glfw.PollEvents(); err != nil { + return err + } } + + return nil } // iconifyWindow must be called from the main thread. -func (u *userInterfaceImpl) iconifyWindow() { +func (u *userInterfaceImpl) iconifyWindow() error { // Iconifying a native fullscreen window on macOS is forbidden. if u.isNativeFullscreen() { - return + return nil } - u.window.Iconify() + if err := u.window.Iconify(); err != nil { + return err + } // On Linux/UNIX, iconifying might not finish even though Iconify returns. Just wait for its finish. - for u.window.GetAttrib(glfw.Iconified) != glfw.True { - glfw.PollEvents() + for { + a, err := u.window.GetAttrib(glfw.Iconified) + if err != nil { + return err + } + if a == glfw.True { + break + } + if err := glfw.PollEvents(); err != nil { + return err + } } + + return nil } // restoreWindow must be called from the main thread. -func (u *userInterfaceImpl) restoreWindow() { - u.window.Restore() +func (u *userInterfaceImpl) restoreWindow() error { + if err := u.window.Restore(); err != nil { + return err + } // On Linux/UNIX, restoring might not finish even though Restore returns (#1608). Just wait for its finish. // On macOS, the restoring state might be the same as the maximized state. Skip this. if runtime.GOOS != "darwin" { - for u.window.GetAttrib(glfw.Maximized) == glfw.True || u.window.GetAttrib(glfw.Iconified) == glfw.True { - glfw.PollEvents() + for { + maximized, err := u.window.GetAttrib(glfw.Maximized) + if err != nil { + return err + } + iconified, err := u.window.GetAttrib(glfw.Iconified) + if err != nil { + return err + } + if maximized == glfw.False && iconified == glfw.False { + break + } + if err := glfw.PollEvents(); err != nil { + return err + } time.Sleep(time.Second / 60) } } + + return nil } // setWindowDecorated must be called from the main thread. -func (u *userInterfaceImpl) setWindowDecorated(decorated bool) { +func (u *userInterfaceImpl) setWindowDecorated(decorated bool) error { if microsoftgdk.IsXbox() { - return + return nil } v := glfw.False if decorated { v = glfw.True } - u.window.SetAttrib(glfw.Decorated, v) + if err := u.window.SetAttrib(glfw.Decorated, v); err != nil { + return err + } // The title can be lost when the decoration is gone. Recover this. if decorated { - u.window.SetTitle(u.title) + if err := u.window.SetTitle(u.title); err != nil { + return err + } } + + return nil } // setWindowFloating must be called from the main thread. -func (u *userInterfaceImpl) setWindowFloating(floating bool) { +func (u *userInterfaceImpl) setWindowFloating(floating bool) error { if microsoftgdk.IsXbox() { - return + return nil } v := glfw.False if floating { v = glfw.True } - u.window.SetAttrib(glfw.Floating, v) + if err := u.window.SetAttrib(glfw.Floating, v); err != nil { + return err + } + + return nil } // setWindowResizingMode must be called from the main thread. -func (u *userInterfaceImpl) setWindowResizingMode(mode WindowResizingMode) { +func (u *userInterfaceImpl) setWindowResizingMode(mode WindowResizingMode) error { if microsoftgdk.IsXbox() { - return + return nil } if u.windowResizingMode == mode { - return + return nil } u.windowResizingMode = mode @@ -1606,8 +2082,12 @@ func (u *userInterfaceImpl) setWindowResizingMode(mode WindowResizingMode) { if mode == WindowResizingModeEnabled { v = glfw.True } - u.window.SetAttrib(glfw.Resizable, v) + if err := u.window.SetAttrib(glfw.Resizable, v); err != nil { + return err + } u.setWindowResizingModeForOS(mode) + + return nil } // setWindowPositionInDIP sets the window position. @@ -1615,31 +2095,44 @@ func (u *userInterfaceImpl) setWindowResizingMode(mode WindowResizingMode) { // x and y are the position in device-independent pixels. // // setWindowPositionInDIP must be called from the main thread. -func (u *userInterfaceImpl) setWindowPositionInDIP(x, y int, monitor *Monitor) { +func (u *userInterfaceImpl) setWindowPositionInDIP(x, y int, monitor *Monitor) error { if microsoftgdk.IsXbox() { // Do nothing. The position is always fixed. - return + return nil + } + + f, err := u.isFullscreen() + if err != nil { + return err } mx := monitor.boundsInGLFWPixels.Min.X my := monitor.boundsInGLFWPixels.Min.Y xf := dipToGLFWPixel(float64(x), monitor) yf := dipToGLFWPixel(float64(y), monitor) - if x, y := u.adjustWindowPosition(mx+int(xf), my+int(yf), monitor); u.isFullscreen() { + if x, y := u.adjustWindowPosition(mx+int(xf), my+int(yf), monitor); f { u.setOrigWindowPos(x, y) } else { - u.window.SetPos(x, y) + if err := u.window.SetPos(x, y); err != nil { + return err + } } + + return nil } // setWindowTitle must be called from the main thread. -func (u *userInterfaceImpl) setWindowTitle(title string) { - u.window.SetTitle(title) +func (u *userInterfaceImpl) setWindowTitle(title string) error { + return u.window.SetTitle(title) } // isWindowMaximized must be called from the main thread. -func (u *userInterfaceImpl) isWindowMaximized() bool { - return u.window.GetAttrib(glfw.Maximized) == glfw.True && !u.isNativeFullscreen() +func (u *userInterfaceImpl) isWindowMaximized() (bool, error) { + a, err := u.window.GetAttrib(glfw.Maximized) + if err != nil { + return false, err + } + return a == glfw.True && !u.isNativeFullscreen(), nil } func (u *userInterfaceImpl) origWindowPos() (int, int) { @@ -1652,16 +2145,19 @@ func (u *userInterfaceImpl) setOrigWindowPos(x, y int) { } // setWindowMousePassthrough must be called from the main thread. -func (u *userInterfaceImpl) setWindowMousePassthrough(enabled bool) { +func (u *userInterfaceImpl) setWindowMousePassthrough(enabled bool) error { if microsoftgdk.IsXbox() { - return + return nil } v := glfw.False if enabled { v = glfw.True } - u.window.SetAttrib(glfw.MousePassthrough, v) + if err := u.window.SetAttrib(glfw.MousePassthrough, v); err != nil { + return err + } + return nil } func IsScreenTransparentAvailable() bool { diff --git a/internal/ui/ui_glfw_darwin.go b/internal/ui/ui_glfw_darwin.go index f8440ba87..b2aadedb7 100644 --- a/internal/ui/ui_glfw_darwin.go +++ b/internal/ui/ui_glfw_darwin.go @@ -122,7 +122,10 @@ func init() { { Cmd: sel_windowWillEnterFullScreen, Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) { - theUI.setOrigWindowPosWithCurrentPos() + if err := theUI.setOrigWindowPosWithCurrentPos(); err != nil { + theGlobalState.setError(err) + return + } pushResizableState(id, cocoa.NSNotification{ID: notification}.Object()) }, }, @@ -139,7 +142,10 @@ func init() { // Even a window has a size limitation, a window can be fullscreen by calling SetFullscreen(true). // In this case, the window size limitation is disabled temporarily. // When exiting from fullscreen, reset the window size limitation. - theUI.updateWindowSizeLimits() + if err := theUI.updateWindowSizeLimits(); err != nil { + theGlobalState.setError(err) + return + } }, }, { @@ -185,9 +191,12 @@ func (*graphicsDriverCreatorImpl) newMetal() (graphicsdriver.Graphics, error) { } // glfwMonitorSizeInGLFWPixels must be called from the main thread. -func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int) { - vm := m.GetVideoMode() - return vm.Width, vm.Height +func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int, error) { + vm, err := m.GetVideoMode() + if err != nil { + return 0, 0, err + } + return vm.Width, vm.Height, nil } func dipFromGLFWPixel(x float64, monitor *Monitor) float64 { @@ -264,7 +273,7 @@ func initialMonitorByOS() (*Monitor, error) { return theMonitors.monitorFromPosition(x, y), nil } -func monitorFromWindowByOS(w *glfw.Window) *Monitor { +func monitorFromWindowByOS(w *glfw.Window) (*Monitor, error) { window := cocoa.NSWindow{ID: objc.ID(w.GetCocoaWindow())} pool := cocoa.NSAutoreleasePool_new() screen := cocoa.NSScreen_mainScreen() @@ -279,14 +288,14 @@ func monitorFromWindowByOS(w *glfw.Window) *Monitor { pool.Release() for _, m := range theMonitors.append(nil) { if m.m.GetCocoaMonitor() == aID { - return m + return m, nil } } - return nil + return nil, nil } -func (u *userInterfaceImpl) nativeWindow() uintptr { - return u.window.GetCocoaWindow() +func (u *userInterfaceImpl) nativeWindow() (uintptr, error) { + return u.window.GetCocoaWindow(), nil } func (u *userInterfaceImpl) isNativeFullscreen() bool { @@ -372,12 +381,13 @@ func (u *userInterfaceImpl) setWindowResizingModeForOS(mode WindowResizingMode) objc.ID(u.window.GetCocoaWindow()).Send(sel_setCollectionBehavior, collectionBehavior) } -func initializeWindowAfterCreation(w *glfw.Window) { +func initializeWindowAfterCreation(w *glfw.Window) error { // TODO: Register NSWindowWillEnterFullScreenNotification and so on. // Enable resizing temporary before making the window fullscreen. nswindow := objc.ID(w.GetCocoaWindow()) delegate := objc.ID(class_EbitengineWindowDelegate).Send(sel_alloc).Send(sel_initWithOrigDelegate, nswindow.Send(sel_delegate)) nswindow.Send(sel_setDelegate, delegate) + return nil } func (u *userInterfaceImpl) skipTaskbar() error { diff --git a/internal/ui/ui_glfw_linbsd.go b/internal/ui/ui_glfw_linbsd.go index 19ea2eb20..723097b75 100644 --- a/internal/ui/ui_glfw_linbsd.go +++ b/internal/ui/ui_glfw_linbsd.go @@ -51,8 +51,11 @@ func (*graphicsDriverCreatorImpl) newMetal() (graphicsdriver.Graphics, error) { } // glfwMonitorSizeInGLFWPixels must be called from the main thread. -func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int) { - vm := m.GetVideoMode() +func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int, error) { + vm, err := m.GetVideoMode() + if err != nil { + return 0, 0, err + } physWidth, physHeight := vm.Width, vm.Height // TODO: if glfw/glfw#1961 gets fixed, this function may need revising. @@ -68,23 +71,27 @@ func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int) { // No X11 connection? // Assume we're on pure Wayland then. // GLFW/Wayland shouldn't be having this issue. - return physWidth, physHeight + return physWidth, physHeight, nil } defer xconn.Close() if err := randr.Init(xconn); err != nil { // No RANDR extension? No problem. - return physWidth, physHeight + return physWidth, physHeight, nil } root := xproto.Setup(xconn).DefaultScreen(xconn).Root res, err := randr.GetScreenResourcesCurrent(xconn, root).Reply() if err != nil { // Likely means RANDR is not working. No problem. - return physWidth, physHeight + return physWidth, physHeight, nil } - monitorX, monitorY := m.GetPos() + monitorX, monitorY, err := m.GetPos() + if err != nil { + // TODO: Is it OK to ignore this error? + return physWidth, physHeight, nil + } for _, crtc := range res.Crtcs[:res.NumCrtcs] { info, err := randr.GetCrtcInfo(xconn, crtc, res.ConfigTimestamp).Reply() @@ -98,12 +105,12 @@ func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int) { continue } if int(info.X) == monitorX && int(info.Y) == monitorY { - return int(info.Width), int(info.Height) + return int(info.Width), int(info.Height), nil } } // Monitor not known to XRandR. Weird. - return physWidth, physHeight + return physWidth, physHeight, nil } func dipFromGLFWPixel(x float64, monitor *Monitor) float64 { @@ -137,14 +144,14 @@ func initialMonitorByOS() (*Monitor, error) { return theMonitors.monitorFromPosition(x, y), nil } -func monitorFromWindowByOS(_ *glfw.Window) *Monitor { +func monitorFromWindowByOS(_ *glfw.Window) (*Monitor, error) { // TODO: Implement this correctly. (#1119). - return nil + return nil, nil } -func (u *userInterfaceImpl) nativeWindow() uintptr { +func (u *userInterfaceImpl) nativeWindow() (uintptr, error) { // TODO: Implement this. - return 0 + return 0, nil } func (u *userInterfaceImpl) isNativeFullscreen() bool { @@ -165,15 +172,18 @@ func (u *userInterfaceImpl) adjustViewSizeAfterFullscreen() { func (u *userInterfaceImpl) setWindowResizingModeForOS(mode WindowResizingMode) { } -func initializeWindowAfterCreation(w *glfw.Window) { +func initializeWindowAfterCreation(w *glfw.Window) error { // Show the window once before getting the position of the window. // On Linux/Unix, the window position is not reliable before showing. - w.Show() + if err := w.Show(); err != nil { + return err + } // Hiding the window makes the position unreliable again. Do not call w.Hide() here (#1829) // Calling Hide is problematic especially on XWayland and/or Sway. // Apparently the window state is inconsistent just after the window is created, but we are not sure. // For more details, see the discussion in #1829. + return nil } func (u *userInterfaceImpl) skipTaskbar() error { diff --git a/internal/ui/ui_glfw_windows.go b/internal/ui/ui_glfw_windows.go index 2f59fe884..044fa0a8d 100644 --- a/internal/ui/ui_glfw_windows.go +++ b/internal/ui/ui_glfw_windows.go @@ -85,9 +85,12 @@ func (*graphicsDriverCreatorImpl) newMetal() (graphicsdriver.Graphics, error) { } // glfwMonitorSizeInGLFWPixels must be called from the main thread. -func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int) { - vm := m.GetVideoMode() - return vm.Width, vm.Height +func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int, error) { + vm, err := m.GetVideoMode() + if err != nil { + return 0, 0, err + } + return vm.Width, vm.Height, nil } func dipFromGLFWPixel(x float64, monitor *Monitor) float64 { @@ -138,11 +141,15 @@ func initialMonitorByOS() (*Monitor, error) { return theMonitors.monitorFromPosition(x, y), nil } -func monitorFromWindowByOS(w *glfw.Window) *Monitor { +func monitorFromWindowByOS(w *glfw.Window) (*Monitor, error) { if microsoftgdk.IsXbox() { - return theMonitors.primaryMonitor() + return theMonitors.primaryMonitor(), nil } - return monitorFromWin32Window(windows.HWND(w.GetWin32Window())) + window, err := w.GetWin32Window() + if err != nil { + return nil, err + } + return monitorFromWin32Window(window), nil } func monitorFromWin32Window(w windows.HWND) *Monitor { @@ -171,8 +178,9 @@ func monitorFromWin32Window(w windows.HWND) *Monitor { return nil } -func (u *userInterfaceImpl) nativeWindow() uintptr { - return u.window.GetWin32Window() +func (u *userInterfaceImpl) nativeWindow() (uintptr, error) { + w, err := u.window.GetWin32Window() + return uintptr(w), err } func (u *userInterfaceImpl) isNativeFullscreen() bool { @@ -193,7 +201,8 @@ func (u *userInterfaceImpl) adjustViewSizeAfterFullscreen() { func (u *userInterfaceImpl) setWindowResizingModeForOS(mode WindowResizingMode) { } -func initializeWindowAfterCreation(w *glfw.Window) { +func initializeWindowAfterCreation(w *glfw.Window) error { + return nil } func (u *userInterfaceImpl) skipTaskbar() error { @@ -212,7 +221,11 @@ func (u *userInterfaceImpl) skipTaskbar() error { t := (*_ITaskbarList)(ptr) defer t.Release() - if err := t.DeleteTab(windows.HWND(u.window.GetWin32Window())); err != nil { + w, err := u.window.GetWin32Window() + if err != nil { + return err + } + if err := t.DeleteTab(w); err != nil { return err } diff --git a/internal/ui/window_glfw.go b/internal/ui/window_glfw.go index b54db5cee..7fb4f87e8 100644 --- a/internal/ui/window_glfw.go +++ b/internal/ui/window_glfw.go @@ -39,7 +39,12 @@ func (w *glfwWindow) IsDecorated() bool { if w.ui.isTerminated() { return } - v = w.ui.window.GetAttrib(glfw.Decorated) == glfw.True + a, err := w.ui.window.GetAttrib(glfw.Decorated) + if err != nil { + theGlobalState.setError(err) + return + } + v = a == glfw.True }) return v } @@ -57,7 +62,10 @@ func (w *glfwWindow) SetDecorated(decorated bool) { if w.ui.isTerminated() { return } - w.ui.setWindowDecorated(decorated) + if err := w.ui.setWindowDecorated(decorated); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -95,7 +103,10 @@ func (w *glfwWindow) SetResizingMode(mode WindowResizingMode) { if w.ui.isTerminated() { return } - w.ui.setWindowResizingMode(mode) + if err := w.ui.setWindowResizingMode(mode); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -111,7 +122,12 @@ func (w *glfwWindow) IsFloating() bool { if w.ui.isTerminated() { return } - v = w.ui.window.GetAttrib(glfw.Floating) == glfw.True + a, err := w.ui.window.GetAttrib(glfw.Floating) + if err != nil { + theGlobalState.setError(err) + return + } + v = a == glfw.True }) return v } @@ -128,7 +144,10 @@ func (w *glfwWindow) SetFloating(floating bool) { if w.ui.isTerminated() { return } - w.ui.setWindowFloating(floating) + if err := w.ui.setWindowFloating(floating); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -147,7 +166,12 @@ func (w *glfwWindow) IsMaximized() bool { if w.ui.isTerminated() { return } - v = w.ui.isWindowMaximized() + m, err := w.ui.isWindowMaximized() + if err != nil { + theGlobalState.setError(err) + return + } + v = m }) return v } @@ -176,7 +200,10 @@ func (w *glfwWindow) Maximize() { if w.ui.isTerminated() { return } - w.ui.maximizeWindow() + if err := w.ui.maximizeWindow(); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -189,7 +216,12 @@ func (w *glfwWindow) IsMinimized() bool { if w.ui.isTerminated() { return } - v = w.ui.window.GetAttrib(glfw.Iconified) == glfw.True + a, err := w.ui.window.GetAttrib(glfw.Iconified) + if err != nil { + theGlobalState.setError(err) + return + } + v = a == glfw.True }) return v } @@ -203,7 +235,10 @@ func (w *glfwWindow) Minimize() { if w.ui.isTerminated() { return } - w.ui.iconifyWindow() + if err := w.ui.iconifyWindow(); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -222,7 +257,10 @@ func (w *glfwWindow) Restore() { if w.ui.isTerminated() { return } - w.ui.restoreWindow() + if err := w.ui.restoreWindow(); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -241,7 +279,10 @@ func (w *glfwWindow) SetMonitor(monitor *Monitor) { if w.ui.isTerminated() { return } - w.ui.setWindowMonitor(monitor) + if err := w.ui.setWindowMonitor(monitor); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -257,13 +298,28 @@ func (w *glfwWindow) Position() (int, int) { if w.ui.isTerminated() { return } + f, err := w.ui.isFullscreen() + if err != nil { + theGlobalState.setError(err) + return + } + var wx, wy int - if w.ui.isFullscreen() { + if f { wx, wy = w.ui.origWindowPos() } else { - wx, wy = w.ui.window.GetPos() + x, y, err := w.ui.window.GetPos() + if err != nil { + theGlobalState.setError(err) + return + } + wx, wy = x, y + } + m, err := w.ui.currentMonitor() + if err != nil { + theGlobalState.setError(err) + return } - m := w.ui.currentMonitor() wx -= m.boundsInGLFWPixels.Min.X wy -= m.boundsInGLFWPixels.Min.Y xf := dipFromGLFWPixel(float64(wx), m) @@ -285,7 +341,15 @@ func (w *glfwWindow) SetPosition(x, y int) { if w.ui.isTerminated() { return } - w.ui.setWindowPositionInDIP(x, y, w.ui.currentMonitor()) + m, err := w.ui.currentMonitor() + if err != nil { + theGlobalState.setError(err) + return + } + if err := w.ui.setWindowPositionInDIP(x, y, m); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -322,10 +386,18 @@ func (w *glfwWindow) SetSize(width, height int) { if w.ui.isTerminated() { return } - if w.ui.isWindowMaximized() && runtime.GOOS != "darwin" { + m, err := w.ui.isWindowMaximized() + if err != nil { + theGlobalState.setError(err) + return + } + if m && runtime.GOOS != "darwin" { + return + } + if err := w.ui.setWindowSizeInDIP(width, height, true); err != nil { + theGlobalState.setError(err) return } - w.ui.setWindowSizeInDIP(width, height, true) }) } @@ -348,7 +420,10 @@ func (w *glfwWindow) SetSizeLimits(minw, minh, maxw, maxh int) { if w.ui.isTerminated() { return } - w.ui.updateWindowSizeLimits() + if err := w.ui.updateWindowSizeLimits(); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -375,7 +450,10 @@ func (w *glfwWindow) SetTitle(title string) { if w.ui.isTerminated() { return } - w.ui.setWindowTitle(title) + if err := w.ui.setWindowTitle(title); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -399,7 +477,10 @@ func (w *glfwWindow) SetMousePassthrough(enabled bool) { if w.ui.isTerminated() { return } - w.ui.setWindowMousePassthrough(enabled) + if err := w.ui.setWindowMousePassthrough(enabled); err != nil { + theGlobalState.setError(err) + return + } }) } @@ -415,7 +496,12 @@ func (w *glfwWindow) IsMousePassthrough() bool { if w.ui.isTerminated() { return } - v = w.ui.window.GetAttrib(glfw.MousePassthrough) == glfw.True + a, err := w.ui.window.GetAttrib(glfw.MousePassthrough) + if err != nil { + theGlobalState.setError(err) + return + } + v = a == glfw.True }) return v }