mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
internal/goglfw: separate the Windows version detection to a new package winver
This commit is contained in:
parent
c0adcee12c
commit
182ac21866
@ -164,11 +164,6 @@ const (
|
|||||||
_TME_LEAVE = 0x00000002
|
_TME_LEAVE = 0x00000002
|
||||||
_UNICODE_NOCHAR = 0xffff
|
_UNICODE_NOCHAR = 0xffff
|
||||||
_USER_DEFAULT_SCREEN_DPI = 96
|
_USER_DEFAULT_SCREEN_DPI = 96
|
||||||
_VER_BUILDNUMBER = 0x00000004
|
|
||||||
_VER_GREATER_EQUAL = 3
|
|
||||||
_VER_MAJORVERSION = 0x00000002
|
|
||||||
_VER_MINORVERSION = 0x00000001
|
|
||||||
_VER_SERVICEPACKMAJOR = 0x00000020
|
|
||||||
_VERTSIZE = 6
|
_VERTSIZE = 6
|
||||||
_VK_ADD = 0x6B
|
_VK_ADD = 0x6B
|
||||||
_VK_CAPITAL = 0x14
|
_VK_CAPITAL = 0x14
|
||||||
@ -262,11 +257,6 @@ const (
|
|||||||
_WGL_TRANSPARENT_INDEX_VALUE_ARB = 0x203B
|
_WGL_TRANSPARENT_INDEX_VALUE_ARB = 0x203B
|
||||||
_WGL_TRANSPARENT_RED_VALUE_ARB = 0x2037
|
_WGL_TRANSPARENT_RED_VALUE_ARB = 0x2037
|
||||||
_WGL_TYPE_RGBA_ARB = 0x202B
|
_WGL_TYPE_RGBA_ARB = 0x202B
|
||||||
_WIN32_WINNT_VISTA = 0x0600
|
|
||||||
_WIN32_WINNT_WIN7 = 0x0601
|
|
||||||
_WIN32_WINNT_WIN8 = 0x0602
|
|
||||||
_WIN32_WINNT_WINBLUE = 0x0603
|
|
||||||
_WIN32_WINNT_WINXP = 0x0501
|
|
||||||
_WM_CAPTURECHANGED = 0x0215
|
_WM_CAPTURECHANGED = 0x0215
|
||||||
_WM_CHAR = 0x0102
|
_WM_CHAR = 0x0102
|
||||||
_WM_CLOSE = 0x0010
|
_WM_CLOSE = 0x0010
|
||||||
@ -387,18 +377,11 @@ func _GET_XBUTTON_WPARAM(wParam _WPARAM) uint16 {
|
|||||||
func _GET_Y_LPARAM(lp _LPARAM) int {
|
func _GET_Y_LPARAM(lp _LPARAM) int {
|
||||||
return int(_HIWORD(uint32(lp)))
|
return int(_HIWORD(uint32(lp)))
|
||||||
}
|
}
|
||||||
func _HIBYTE(wValue uint16) byte {
|
|
||||||
return byte(wValue >> 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _HIWORD(dwValue uint32) uint16 {
|
func _HIWORD(dwValue uint32) uint16 {
|
||||||
return uint16(dwValue >> 16)
|
return uint16(dwValue >> 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
func _LOBYTE(wValue uint16) byte {
|
|
||||||
return byte(wValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _LOWORD(dwValue uint32) uint16 {
|
func _LOWORD(dwValue uint32) uint16 {
|
||||||
return uint16(dwValue)
|
return uint16(dwValue)
|
||||||
}
|
}
|
||||||
@ -590,20 +573,6 @@ type _MSG struct {
|
|||||||
lPrivate uint32
|
lPrivate uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type _OSVERSIONINFOEXW struct {
|
|
||||||
dwOSVersionInfoSize uint32
|
|
||||||
dwMajorVersion uint32
|
|
||||||
dwMinorVersion uint32
|
|
||||||
dwBuildNumber uint32
|
|
||||||
dwPlatformId uint32
|
|
||||||
szCSDVersion [128]uint16
|
|
||||||
wServicePackMajor uint16
|
|
||||||
wServicePackMinor uint16
|
|
||||||
wSuiteMask uint16
|
|
||||||
wProductType byte
|
|
||||||
wReserved byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type _PIXELFORMATDESCRIPTOR struct {
|
type _PIXELFORMATDESCRIPTOR struct {
|
||||||
nSize uint16
|
nSize uint16
|
||||||
nVersion uint16
|
nVersion uint16
|
||||||
@ -722,7 +691,6 @@ var (
|
|||||||
dwmapi = windows.NewLazySystemDLL("dwmapi.dll")
|
dwmapi = windows.NewLazySystemDLL("dwmapi.dll")
|
||||||
gdi32 = windows.NewLazySystemDLL("gdi32.dll")
|
gdi32 = windows.NewLazySystemDLL("gdi32.dll")
|
||||||
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
ntdll = windows.NewLazySystemDLL("ntdll.dll")
|
|
||||||
opengl32 = windows.NewLazySystemDLL("opengl32.dll")
|
opengl32 = windows.NewLazySystemDLL("opengl32.dll")
|
||||||
shcore = windows.NewLazySystemDLL("shcore.dll")
|
shcore = windows.NewLazySystemDLL("shcore.dll")
|
||||||
shell32 = windows.NewLazySystemDLL("shell32.dll")
|
shell32 = windows.NewLazySystemDLL("shell32.dll")
|
||||||
@ -749,9 +717,6 @@ var (
|
|||||||
procTlsFree = kernel32.NewProc("TlsFree")
|
procTlsFree = kernel32.NewProc("TlsFree")
|
||||||
procTlsGetValue = kernel32.NewProc("TlsGetValue")
|
procTlsGetValue = kernel32.NewProc("TlsGetValue")
|
||||||
procTlsSetValue = kernel32.NewProc("TlsSetValue")
|
procTlsSetValue = kernel32.NewProc("TlsSetValue")
|
||||||
procVerSetConditionMask = kernel32.NewProc("VerSetConditionMask")
|
|
||||||
|
|
||||||
procRtlVerifyVersionInfo = ntdll.NewProc("RtlVerifyVersionInfo")
|
|
||||||
|
|
||||||
procWGLCreateContext = opengl32.NewProc("wglCreateContext")
|
procWGLCreateContext = opengl32.NewProc("wglCreateContext")
|
||||||
procWGLDeleteContext = opengl32.NewProc("wglDeleteContext")
|
procWGLDeleteContext = opengl32.NewProc("wglDeleteContext")
|
||||||
@ -1522,24 +1487,6 @@ func _ReleaseDC(hWnd windows.HWND, hDC _HDC) int32 {
|
|||||||
return int32(r)
|
return int32(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func _RtlVerifyVersionInfo(versionInfo *_OSVERSIONINFOEXW, typeMask uint32, conditionMask uint64) int32 {
|
|
||||||
var r uintptr
|
|
||||||
if unsafe.Sizeof(uintptr(0)) == unsafe.Sizeof(uint64(0)) {
|
|
||||||
r, _, _ = procRtlVerifyVersionInfo.Call(uintptr(unsafe.Pointer(versionInfo)), uintptr(typeMask), uintptr(conditionMask))
|
|
||||||
} else {
|
|
||||||
switch runtime.GOARCH {
|
|
||||||
case "386":
|
|
||||||
r, _, _ = procRtlVerifyVersionInfo.Call(uintptr(unsafe.Pointer(versionInfo)), uintptr(typeMask), uintptr(conditionMask), uintptr(conditionMask>>32))
|
|
||||||
case "arm":
|
|
||||||
// Adjust the alignment for ARM.
|
|
||||||
r, _, _ = procRtlVerifyVersionInfo.Call(uintptr(unsafe.Pointer(versionInfo)), uintptr(typeMask), 0, uintptr(conditionMask), uintptr(conditionMask>>32))
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("goglfw: GOARCH=%s is not supported", runtime.GOARCH))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return int32(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ScreenToClient(hWnd windows.HWND, lpPoint *_POINT) error {
|
func _ScreenToClient(hWnd windows.HWND, lpPoint *_POINT) error {
|
||||||
r, _, e := procScreenToClient.Call(uintptr(hWnd), uintptr(unsafe.Pointer(lpPoint)))
|
r, _, e := procScreenToClient.Call(uintptr(hWnd), uintptr(unsafe.Pointer(lpPoint)))
|
||||||
if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) {
|
if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) {
|
||||||
@ -1777,16 +1724,6 @@ func _UnregisterDeviceNotification(handle _HDEVNOTIFY) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func _VerSetConditionMask(conditionMask uint64, typeMask uint32, condition byte) uint64 {
|
|
||||||
if unsafe.Sizeof(uintptr(0)) == unsafe.Sizeof(uint64(0)) {
|
|
||||||
r, _, _ := procVerSetConditionMask.Call(uintptr(conditionMask), uintptr(typeMask), uintptr(condition))
|
|
||||||
return uint64(r)
|
|
||||||
} else {
|
|
||||||
r1, r2, _ := procVerSetConditionMask.Call(uintptr(conditionMask), uintptr(conditionMask>>32), uintptr(typeMask), uintptr(condition))
|
|
||||||
return uint64(r1) | (uint64(r2) << 32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func _WaitMessage() error {
|
func _WaitMessage() error {
|
||||||
r, _, e := procWaitMessage.Call()
|
r, _, e := procWaitMessage.Call()
|
||||||
if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) {
|
if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) {
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/winver"
|
||||||
)
|
)
|
||||||
|
|
||||||
func findPixelFormatAttribValue(attribs []int32, values []int32, attrib int32) int32 {
|
func findPixelFormatAttribValue(attribs []int32, values []int32, attrib int32) int32 {
|
||||||
@ -230,9 +231,9 @@ func makeContextCurrentWGL(window *Window) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func swapBuffersWGL(window *Window) error {
|
func swapBuffersWGL(window *Window) error {
|
||||||
if window.monitor == nil && _IsWindowsVistaOrGreater() {
|
if window.monitor == nil && winver.IsWindowsVistaOrGreater() {
|
||||||
// DWM Composition is always enabled on Win8+
|
// DWM Composition is always enabled on Win8+
|
||||||
enabled := _IsWindows8OrGreater()
|
enabled := winver.IsWindows8OrGreater()
|
||||||
|
|
||||||
if !enabled {
|
if !enabled {
|
||||||
var err error
|
var err error
|
||||||
@ -266,9 +267,9 @@ func swapIntervalWGL(interval int) error {
|
|||||||
|
|
||||||
window.context.platform.interval = interval
|
window.context.platform.interval = interval
|
||||||
|
|
||||||
if window.monitor == nil && _IsWindowsVistaOrGreater() {
|
if window.monitor == nil && winver.IsWindowsVistaOrGreater() {
|
||||||
// DWM Composition is always enabled on Win8+
|
// DWM Composition is always enabled on Win8+
|
||||||
enabled := _IsWindows8OrGreater()
|
enabled := winver.IsWindows8OrGreater()
|
||||||
|
|
||||||
if !enabled {
|
if !enabled {
|
||||||
e, err := _DwmIsCompositionEnabled()
|
e, err := _DwmIsCompositionEnabled()
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/winver"
|
||||||
)
|
)
|
||||||
|
|
||||||
func createKeyTables() {
|
func createKeyTables() {
|
||||||
@ -238,41 +239,6 @@ func createHelperWindow() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func isWindowsVersionOrGreaterWin32(major, minor, sp uint16) bool {
|
|
||||||
osvi := _OSVERSIONINFOEXW{
|
|
||||||
dwMajorVersion: uint32(major),
|
|
||||||
dwMinorVersion: uint32(minor),
|
|
||||||
wServicePackMajor: sp,
|
|
||||||
}
|
|
||||||
osvi.dwOSVersionInfoSize = uint32(unsafe.Sizeof(osvi))
|
|
||||||
var mask uint32 = _VER_MAJORVERSION | _VER_MINORVERSION | _VER_SERVICEPACKMAJOR
|
|
||||||
cond := _VerSetConditionMask(0, _VER_MAJORVERSION, _VER_GREATER_EQUAL)
|
|
||||||
cond = _VerSetConditionMask(cond, _VER_MINORVERSION, _VER_GREATER_EQUAL)
|
|
||||||
cond = _VerSetConditionMask(cond, _VER_SERVICEPACKMAJOR, _VER_GREATER_EQUAL)
|
|
||||||
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
|
||||||
// latter lies unless the user knew to embed a non-default manifest
|
|
||||||
// announcing support for Windows 10 via supportedOS GUID
|
|
||||||
return _RtlVerifyVersionInfo(&osvi, mask, cond) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func isWindows10BuildOrGreaterWin32(build uint16) bool {
|
|
||||||
osvi := _OSVERSIONINFOEXW{
|
|
||||||
dwMajorVersion: 10,
|
|
||||||
dwMinorVersion: 0,
|
|
||||||
dwBuildNumber: uint32(build),
|
|
||||||
}
|
|
||||||
osvi.dwOSVersionInfoSize = uint32(unsafe.Sizeof(osvi))
|
|
||||||
var mask uint32 = _VER_MAJORVERSION | _VER_MINORVERSION | _VER_BUILDNUMBER
|
|
||||||
cond := _VerSetConditionMask(0, _VER_MAJORVERSION, _VER_GREATER_EQUAL)
|
|
||||||
cond = _VerSetConditionMask(cond, _VER_MINORVERSION, _VER_GREATER_EQUAL)
|
|
||||||
cond = _VerSetConditionMask(cond, _VER_BUILDNUMBER, _VER_GREATER_EQUAL)
|
|
||||||
|
|
||||||
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
|
||||||
// latter lies unless the user knew to embed a non-default manifest
|
|
||||||
// announcing support for Windows 10 via supportedOS GUID
|
|
||||||
return _RtlVerifyVersionInfo(&osvi, mask, cond) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func platformInit() error {
|
func platformInit() error {
|
||||||
// Changing the foreground lock timeout was removed from the original code.
|
// Changing the foreground lock timeout was removed from the original code.
|
||||||
// See https://github.com/glfw/glfw/commit/58b48a3a00d9c2a5ca10cc23069a71d8773cc7a4
|
// See https://github.com/glfw/glfw/commit/58b48a3a00d9c2a5ca10cc23069a71d8773cc7a4
|
||||||
@ -286,17 +252,17 @@ func platformInit() error {
|
|||||||
createKeyTables()
|
createKeyTables()
|
||||||
updateKeyNamesWin32()
|
updateKeyNamesWin32()
|
||||||
|
|
||||||
if isWindows10CreatorsUpdateOrGreaterWin32() {
|
if winver.IsWindows10CreatorsUpdateOrGreater() {
|
||||||
if !microsoftgdk.IsXbox() {
|
if !microsoftgdk.IsXbox() {
|
||||||
// Ignore the error as SetProcessDpiAwarenessContext returns an error on Steam Deck (#2113).
|
// Ignore the error as SetProcessDpiAwarenessContext returns an error on Steam Deck (#2113).
|
||||||
// This seems an issue in Wine and/or Proton, but there is nothing we can do.
|
// This seems an issue in Wine and/or Proton, but there is nothing we can do.
|
||||||
_ = _SetProcessDpiAwarenessContext(_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)
|
_ = _SetProcessDpiAwarenessContext(_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)
|
||||||
}
|
}
|
||||||
} else if _IsWindows8Point1OrGreater() {
|
} else if winver.IsWindows8Point1OrGreater() {
|
||||||
if err := _SetProcessDpiAwareness(_PROCESS_PER_MONITOR_DPI_AWARE); err != nil && !errors.Is(err, handleError(windows.E_ACCESSDENIED)) {
|
if err := _SetProcessDpiAwareness(_PROCESS_PER_MONITOR_DPI_AWARE); err != nil && !errors.Is(err, handleError(windows.E_ACCESSDENIED)) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if _IsWindowsVistaOrGreater() {
|
} else if winver.IsWindowsVistaOrGreater() {
|
||||||
_SetProcessDPIAware()
|
_SetProcessDPIAware()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/winver"
|
||||||
)
|
)
|
||||||
|
|
||||||
func monitorCallback(handle _HMONITOR, dc _HDC, rect *_RECT, monitor *Monitor /* _LPARAM */) uintptr /* _BOOL */ {
|
func monitorCallback(handle _HMONITOR, dc _HDC, rect *_RECT, monitor *Monitor /* _LPARAM */) uintptr /* _BOOL */ {
|
||||||
@ -217,7 +218,7 @@ func (m *Monitor) restoreVideoModeWin32() {
|
|||||||
func getMonitorContentScaleWin32(handle _HMONITOR) (xscale, yscale float32, err error) {
|
func getMonitorContentScaleWin32(handle _HMONITOR) (xscale, yscale float32, err error) {
|
||||||
var xdpi, ydpi uint32
|
var xdpi, ydpi uint32
|
||||||
|
|
||||||
if _IsWindows8Point1OrGreater() {
|
if winver.IsWindows8Point1OrGreater() {
|
||||||
var err error
|
var err error
|
||||||
xdpi, ydpi, err = _GetDpiForMonitor(handle, _MDT_EFFECTIVE_DPI)
|
xdpi, ydpi, err = _GetDpiForMonitor(handle, _MDT_EFFECTIVE_DPI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
package goglfw
|
package goglfw
|
||||||
|
|
||||||
import "golang.org/x/sys/windows"
|
import (
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_GLFW_WNDCLASSNAME = "GLFW30"
|
_GLFW_WNDCLASSNAME = "GLFW30"
|
||||||
@ -96,31 +98,3 @@ type platformLibraryContextState struct {
|
|||||||
ARB_create_context_no_error bool
|
ARB_create_context_no_error bool
|
||||||
ARB_context_flush_control bool
|
ARB_context_flush_control bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func _IsWindowsXPOrGreater() bool {
|
|
||||||
return isWindowsVersionOrGreaterWin32(uint16(_HIBYTE(_WIN32_WINNT_WINXP)), uint16(_LOBYTE(_WIN32_WINNT_WINXP)), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IsWindowsVistaOrGreater() bool {
|
|
||||||
return isWindowsVersionOrGreaterWin32(uint16(_HIBYTE(_WIN32_WINNT_VISTA)), uint16(_LOBYTE(_WIN32_WINNT_VISTA)), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IsWindows7OrGreater() bool {
|
|
||||||
return isWindowsVersionOrGreaterWin32(uint16(_HIBYTE(_WIN32_WINNT_WIN7)), uint16(_LOBYTE(_WIN32_WINNT_WIN7)), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IsWindows8OrGreater() bool {
|
|
||||||
return isWindowsVersionOrGreaterWin32(uint16(_HIBYTE(_WIN32_WINNT_WIN8)), uint16(_LOBYTE(_WIN32_WINNT_WIN8)), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IsWindows8Point1OrGreater() bool {
|
|
||||||
return isWindowsVersionOrGreaterWin32(uint16(_HIBYTE(_WIN32_WINNT_WINBLUE)), uint16(_LOBYTE(_WIN32_WINNT_WINBLUE)), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isWindows10AnniversaryUpdateOrGreaterWin32() bool {
|
|
||||||
return isWindows10BuildOrGreaterWin32(14393)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isWindows10CreatorsUpdateOrGreaterWin32() bool {
|
|
||||||
return isWindows10BuildOrGreaterWin32(15063)
|
|
||||||
}
|
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/winver"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *Window) getWindowStyle() uint32 {
|
func (w *Window) getWindowStyle() uint32 {
|
||||||
@ -137,7 +138,7 @@ func getFullWindowSize(style uint32, exStyle uint32, contentWidth, contentHeight
|
|||||||
right: int32(contentWidth),
|
right: int32(contentWidth),
|
||||||
bottom: int32(contentHeight),
|
bottom: int32(contentHeight),
|
||||||
}
|
}
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
if err := _AdjustWindowRectExForDpi(&rect, style, false, exStyle, dpi); err != nil {
|
if err := _AdjustWindowRectExForDpi(&rect, style, false, exStyle, dpi); err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
@ -153,7 +154,7 @@ func (w *Window) applyAspectRatio(edge int, area *_RECT) error {
|
|||||||
ratio := float32(w.numer) / float32(w.denom)
|
ratio := float32(w.numer) / float32(w.denom)
|
||||||
|
|
||||||
var dpi uint32 = _USER_DEFAULT_SCREEN_DPI
|
var dpi uint32 = _USER_DEFAULT_SCREEN_DPI
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
dpi = _GetDpiForWindow(w.platform.handle)
|
dpi = _GetDpiForWindow(w.platform.handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,7 +344,7 @@ func (w *Window) updateWindowStyles() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
if err := _AdjustWindowRectExForDpi(&rect, style, false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
if err := _AdjustWindowRectExForDpi(&rect, style, false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -368,7 +369,7 @@ func (w *Window) updateWindowStyles() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) updateFramebufferTransparency() error {
|
func (w *Window) updateFramebufferTransparency() error {
|
||||||
if !_IsWindowsVistaOrGreater() {
|
if !winver.IsWindowsVistaOrGreater() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +383,7 @@ func (w *Window) updateFramebufferTransparency() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var opaque bool
|
var opaque bool
|
||||||
if !_IsWindows8OrGreater() {
|
if !winver.IsWindows8OrGreater() {
|
||||||
_, opaque, err = _DwmGetColorizationColor()
|
_, opaque, err = _DwmGetColorizationColor()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Ignore an error from DWM functions as they might not be implemented e.g. on Proton (#2113).
|
// Ignore an error from DWM functions as they might not be implemented e.g. on Proton (#2113).
|
||||||
@ -390,7 +391,7 @@ func (w *Window) updateFramebufferTransparency() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _IsWindows8OrGreater() || !opaque {
|
if winver.IsWindows8OrGreater() || !opaque {
|
||||||
region, err := _CreateRectRgn(0, 0, -1, -1)
|
region, err := _CreateRectRgn(0, 0, -1, -1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -473,7 +474,7 @@ func (w *Window) acquireMonitor() error {
|
|||||||
|
|
||||||
// HACK: When mouse trails are enabled the cursor becomes invisible when
|
// HACK: When mouse trails are enabled the cursor becomes invisible when
|
||||||
// the OpenGL ICD switches to page flipping
|
// the OpenGL ICD switches to page flipping
|
||||||
if _IsWindowsXPOrGreater() {
|
if winver.IsWindowsXPOrGreater() {
|
||||||
if err := _SystemParametersInfoW(_SPI_GETMOUSETRAILS, 0, uintptr(unsafe.Pointer(&_glfw.platformWindow.mouseTrailSize)), 0); err != nil {
|
if err := _SystemParametersInfoW(_SPI_GETMOUSETRAILS, 0, uintptr(unsafe.Pointer(&_glfw.platformWindow.mouseTrailSize)), 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -504,7 +505,7 @@ func (w *Window) releaseMonitor() error {
|
|||||||
_SetThreadExecutionState(_ES_CONTINUOUS)
|
_SetThreadExecutionState(_ES_CONTINUOUS)
|
||||||
|
|
||||||
// HACK: Restore mouse trail length saved in acquireMonitor
|
// HACK: Restore mouse trail length saved in acquireMonitor
|
||||||
if _IsWindowsXPOrGreater() {
|
if winver.IsWindowsXPOrGreater() {
|
||||||
if err := _SystemParametersInfoW(_SPI_SETMOUSETRAILS, _glfw.platformWindow.mouseTrailSize, 0, 0); err != nil {
|
if err := _SystemParametersInfoW(_SPI_SETMOUSETRAILS, _glfw.platformWindow.mouseTrailSize, 0, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -546,7 +547,7 @@ func (w *Window) maximizeWindowManually() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
exStyle := uint32(s)
|
exStyle := uint32(s)
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
dpi := _GetDpiForWindow(w.platform.handle)
|
dpi := _GetDpiForWindow(w.platform.handle)
|
||||||
if err := _AdjustWindowRectExForDpi(&rect, style, false, exStyle, dpi); err != nil {
|
if err := _AdjustWindowRectExForDpi(&rect, style, false, exStyle, dpi); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -588,7 +589,7 @@ func windowProc(hWnd windows.HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM)
|
|||||||
// and for a regular window during its initial creation
|
// and for a regular window during its initial creation
|
||||||
switch uMsg {
|
switch uMsg {
|
||||||
case _WM_NCCREATE:
|
case _WM_NCCREATE:
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
cs := (*_CREATESTRUCTW)(unsafe.Pointer(lParam))
|
cs := (*_CREATESTRUCTW)(unsafe.Pointer(lParam))
|
||||||
wndconfig := (*wndconfig)(cs.lpCreateParams)
|
wndconfig := (*wndconfig)(cs.lpCreateParams)
|
||||||
|
|
||||||
@ -1062,7 +1063,7 @@ func windowProc(hWnd windows.HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM)
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
dpi = _GetDpiForWindow(window.platform.handle)
|
dpi = _GetDpiForWindow(window.platform.handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1122,7 +1123,7 @@ func windowProc(hWnd windows.HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the window size to keep the content area size constant
|
// Adjust the window size to keep the content area size constant
|
||||||
if isWindows10CreatorsUpdateOrGreaterWin32() {
|
if winver.IsWindows10CreatorsUpdateOrGreater() {
|
||||||
var source, target _RECT
|
var source, target _RECT
|
||||||
size := (*_SIZE)(unsafe.Pointer(lParam))
|
size := (*_SIZE)(unsafe.Pointer(lParam))
|
||||||
|
|
||||||
@ -1146,7 +1147,7 @@ func windowProc(hWnd windows.HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM)
|
|||||||
|
|
||||||
// Resize windowed mode windows that either permit rescaling or that
|
// Resize windowed mode windows that either permit rescaling or that
|
||||||
// need it to compensate for non-client area scaling
|
// need it to compensate for non-client area scaling
|
||||||
if window.monitor == nil && (window.platform.scaleToMonitor || isWindows10CreatorsUpdateOrGreaterWin32()) {
|
if window.monitor == nil && (window.platform.scaleToMonitor || winver.IsWindows10CreatorsUpdateOrGreater()) {
|
||||||
suggested := (*_RECT)(unsafe.Pointer(lParam))
|
suggested := (*_RECT)(unsafe.Pointer(lParam))
|
||||||
if err := _SetWindowPos(window.platform.handle, _HWND_TOP,
|
if err := _SetWindowPos(window.platform.handle, _HWND_TOP,
|
||||||
suggested.left,
|
suggested.left,
|
||||||
@ -1244,7 +1245,7 @@ func (w *Window) createNativeWindow(wndconfig *wndconfig, fbconfig *fbconfig) er
|
|||||||
|
|
||||||
handleToWindow[w.platform.handle] = w
|
handleToWindow[w.platform.handle] = w
|
||||||
|
|
||||||
if !microsoftgdk.IsXbox() && _IsWindows7OrGreater() {
|
if !microsoftgdk.IsXbox() && winver.IsWindows7OrGreater() {
|
||||||
if err := _ChangeWindowMessageFilterEx(w.platform.handle, _WM_DROPFILES, _MSGFLT_ALLOW, nil); err != nil {
|
if err := _ChangeWindowMessageFilterEx(w.platform.handle, _WM_DROPFILES, _MSGFLT_ALLOW, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1291,7 +1292,7 @@ func (w *Window) createNativeWindow(wndconfig *wndconfig, fbconfig *fbconfig) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
if err := _AdjustWindowRectExForDpi(&rect, style, false, exStyle, _GetDpiForWindow(w.platform.handle)); err != nil {
|
if err := _AdjustWindowRectExForDpi(&rect, style, false, exStyle, _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1577,7 +1578,7 @@ func (w *Window) platformSetWindowPos(xpos, ypos int) error {
|
|||||||
right: int32(xpos),
|
right: int32(xpos),
|
||||||
bottom: int32(ypos),
|
bottom: int32(ypos),
|
||||||
}
|
}
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1619,7 +1620,7 @@ func (w *Window) platformSetWindowSize(width, height int) error {
|
|||||||
bottom: int32(height),
|
bottom: int32(height),
|
||||||
}
|
}
|
||||||
|
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1688,7 +1689,7 @@ func (w *Window) platformGetWindowFrameSize() (left, top, right, bottom int, err
|
|||||||
right: int32(width),
|
right: int32(width),
|
||||||
bottom: int32(height),
|
bottom: int32(height),
|
||||||
}
|
}
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||||
return 0, 0, 0, 0, err
|
return 0, 0, 0, 0, err
|
||||||
}
|
}
|
||||||
@ -1770,7 +1771,7 @@ func (w *Window) platformSetWindowMonitor(monitor *Monitor, xpos, ypos, width, h
|
|||||||
right: int32(xpos + width),
|
right: int32(xpos + width),
|
||||||
bottom: int32(ypos + height),
|
bottom: int32(ypos + height),
|
||||||
}
|
}
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1853,7 +1854,7 @@ func (w *Window) platformSetWindowMonitor(monitor *Monitor, xpos, ypos, width, h
|
|||||||
right: int32(xpos + width),
|
right: int32(xpos + width),
|
||||||
bottom: int32(ypos + height),
|
bottom: int32(ypos + height),
|
||||||
}
|
}
|
||||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||||
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(),
|
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(),
|
||||||
false, w.getWindowExStyle(),
|
false, w.getWindowExStyle(),
|
||||||
_GetDpiForWindow(w.platform.handle)); err != nil {
|
_GetDpiForWindow(w.platform.handle)); err != nil {
|
||||||
@ -1926,7 +1927,7 @@ func (w *Window) platformFramebufferTransparent() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !_IsWindowsVistaOrGreater() {
|
if !winver.IsWindowsVistaOrGreater() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1935,7 +1936,7 @@ func (w *Window) platformFramebufferTransparent() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !_IsWindows8OrGreater() {
|
if !winver.IsWindows8OrGreater() {
|
||||||
// HACK: Disable framebuffer transparency on Windows 7 when the
|
// HACK: Disable framebuffer transparency on Windows 7 when the
|
||||||
// colorization color is opaque, because otherwise the window
|
// colorization color is opaque, because otherwise the window
|
||||||
// contents is blended additively with the previous frame instead
|
// contents is blended additively with the previous frame instead
|
||||||
|
@ -16,7 +16,6 @@ package directx
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
@ -24,13 +23,6 @@ import (
|
|||||||
|
|
||||||
const is64bit = unsafe.Sizeof(uintptr(0)) == 8
|
const is64bit = unsafe.Sizeof(uintptr(0)) == 8
|
||||||
|
|
||||||
const (
|
|
||||||
_VER_BUILDNUMBER = 0x00000004
|
|
||||||
_VER_GREATER_EQUAL = 3
|
|
||||||
_VER_MAJORVERSION = 0x00000002
|
|
||||||
_VER_MINORVERSION = 0x00000001
|
|
||||||
)
|
|
||||||
|
|
||||||
type handleError windows.Handle
|
type handleError windows.Handle
|
||||||
|
|
||||||
func (h handleError) Error() string {
|
func (h handleError) Error() string {
|
||||||
@ -48,33 +40,13 @@ func boolToUintptr(v bool) uintptr {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type _OSVERSIONINFOEXW struct {
|
|
||||||
dwOSVersionInfoSize uint32
|
|
||||||
dwMajorVersion uint32
|
|
||||||
dwMinorVersion uint32
|
|
||||||
dwBuildNumber uint32
|
|
||||||
dwPlatformId uint32
|
|
||||||
szCSDVersion [128]uint16
|
|
||||||
wServicePackMajor uint16
|
|
||||||
wServicePackMinor uint16
|
|
||||||
wSuiteMask uint16
|
|
||||||
wProductType byte
|
|
||||||
wReserved byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type _PAPPSTATE_CHANGE_ROUTINE func(quiesced bool, context unsafe.Pointer) uintptr
|
type _PAPPSTATE_CHANGE_ROUTINE func(quiesced bool, context unsafe.Pointer) uintptr
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// https://github.com/MicrosoftDocs/sdk-api/blob/docs/sdk-api-src/content/appnotify/nf-appnotify-registerappstatechangenotification.md
|
// https://github.com/MicrosoftDocs/sdk-api/blob/docs/sdk-api-src/content/appnotify/nf-appnotify-registerappstatechangenotification.md
|
||||||
appnotify = windows.NewLazySystemDLL("API-MS-Win-Core-psm-appnotify-l1-1-0.dll")
|
appnotify = windows.NewLazySystemDLL("API-MS-Win-Core-psm-appnotify-l1-1-0.dll")
|
||||||
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
|
||||||
ntdll = windows.NewLazySystemDLL("ntdll.dll")
|
|
||||||
|
|
||||||
procRegisterAppStateChangeNotification = appnotify.NewProc("RegisterAppStateChangeNotification")
|
procRegisterAppStateChangeNotification = appnotify.NewProc("RegisterAppStateChangeNotification")
|
||||||
|
|
||||||
procVerSetConditionMask = kernel32.NewProc("VerSetConditionMask")
|
|
||||||
|
|
||||||
procRtlVerifyVersionInfo = ntdll.NewProc("RtlVerifyVersionInfo")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func _RegisterAppStateChangeNotification(routine _PAPPSTATE_CHANGE_ROUTINE, context unsafe.Pointer) (unsafe.Pointer, error) {
|
func _RegisterAppStateChangeNotification(routine _PAPPSTATE_CHANGE_ROUTINE, context unsafe.Pointer) (unsafe.Pointer, error) {
|
||||||
@ -86,45 +58,3 @@ func _RegisterAppStateChangeNotification(routine _PAPPSTATE_CHANGE_ROUTINE, cont
|
|||||||
}
|
}
|
||||||
return registration, nil
|
return registration, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func _RtlVerifyVersionInfo(versionInfo *_OSVERSIONINFOEXW, typeMask uint32, conditionMask uint64) int32 {
|
|
||||||
var r uintptr
|
|
||||||
if is64bit {
|
|
||||||
r, _, _ = procRtlVerifyVersionInfo.Call(uintptr(unsafe.Pointer(versionInfo)), uintptr(typeMask), uintptr(conditionMask))
|
|
||||||
} else {
|
|
||||||
switch runtime.GOARCH {
|
|
||||||
case "386":
|
|
||||||
r, _, _ = procRtlVerifyVersionInfo.Call(uintptr(unsafe.Pointer(versionInfo)), uintptr(typeMask), uintptr(conditionMask), uintptr(conditionMask>>32))
|
|
||||||
case "arm":
|
|
||||||
// Adjust the alignment for ARM.
|
|
||||||
r, _, _ = procRtlVerifyVersionInfo.Call(uintptr(unsafe.Pointer(versionInfo)), uintptr(typeMask), 0, uintptr(conditionMask), uintptr(conditionMask>>32))
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("directx: GOARCH=%s is not supported", runtime.GOARCH))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return int32(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _VerSetConditionMask(conditionMask uint64, typeMask uint32, condition byte) uint64 {
|
|
||||||
if is64bit {
|
|
||||||
r, _, _ := procVerSetConditionMask.Call(uintptr(conditionMask), uintptr(typeMask), uintptr(condition))
|
|
||||||
return uint64(r)
|
|
||||||
} else {
|
|
||||||
r1, r2, _ := procVerSetConditionMask.Call(uintptr(conditionMask), uintptr(conditionMask>>32), uintptr(typeMask), uintptr(condition))
|
|
||||||
return uint64(r1) | (uint64(r2) << 32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func isWindows10OrGreaterWin32() bool {
|
|
||||||
osvi := _OSVERSIONINFOEXW{
|
|
||||||
dwMajorVersion: 10,
|
|
||||||
dwMinorVersion: 0,
|
|
||||||
dwBuildNumber: 0,
|
|
||||||
}
|
|
||||||
osvi.dwOSVersionInfoSize = uint32(unsafe.Sizeof(osvi))
|
|
||||||
var mask uint32 = _VER_MAJORVERSION | _VER_MINORVERSION | _VER_BUILDNUMBER
|
|
||||||
cond := _VerSetConditionMask(0, _VER_MAJORVERSION, _VER_GREATER_EQUAL)
|
|
||||||
cond = _VerSetConditionMask(cond, _VER_MINORVERSION, _VER_GREATER_EQUAL)
|
|
||||||
cond = _VerSetConditionMask(cond, _VER_BUILDNUMBER, _VER_GREATER_EQUAL)
|
|
||||||
return _RtlVerifyVersionInfo(&osvi, mask, cond) == 0
|
|
||||||
}
|
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/winver"
|
||||||
)
|
)
|
||||||
|
|
||||||
type stencilMode int
|
type stencilMode int
|
||||||
@ -275,7 +276,7 @@ func (g *graphicsInfra) initSwapChain(width, height int, device unsafe.Pointer,
|
|||||||
|
|
||||||
// DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL/DISCARD are not supported for older Windows than 10 or DirectX 12.
|
// DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL/DISCARD are not supported for older Windows than 10 or DirectX 12.
|
||||||
// https://learn.microsoft.com/en-us/windows/win32/api/dxgi/ne-dxgi-dxgi_swap_effect
|
// https://learn.microsoft.com/en-us/windows/win32/api/dxgi/ne-dxgi-dxgi_swap_effect
|
||||||
if !isWindows10OrGreaterWin32() {
|
if !winver.IsWindows10OrGreater() {
|
||||||
desc.SwapEffect = _DXGI_SWAP_EFFECT_SEQUENTIAL
|
desc.SwapEffect = _DXGI_SWAP_EFFECT_SEQUENTIAL
|
||||||
desc.BufferCount = 1
|
desc.BufferCount = 1
|
||||||
}
|
}
|
||||||
|
95
internal/winver/api_windows.go
Normal file
95
internal/winver/api_windows.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Copyright 2023 The Ebitengine 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 winver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
_VER_BUILDNUMBER = 0x00000004
|
||||||
|
_VER_GREATER_EQUAL = 3
|
||||||
|
_VER_MAJORVERSION = 0x00000002
|
||||||
|
_VER_MINORVERSION = 0x00000001
|
||||||
|
_VER_SERVICEPACKMAJOR = 0x00000020
|
||||||
|
_WIN32_WINNT_VISTA = 0x0600
|
||||||
|
_WIN32_WINNT_WIN7 = 0x0601
|
||||||
|
_WIN32_WINNT_WIN8 = 0x0602
|
||||||
|
_WIN32_WINNT_WINBLUE = 0x0603
|
||||||
|
_WIN32_WINNT_WINXP = 0x0501
|
||||||
|
)
|
||||||
|
|
||||||
|
type _OSVERSIONINFOEXW struct {
|
||||||
|
dwOSVersionInfoSize uint32
|
||||||
|
dwMajorVersion uint32
|
||||||
|
dwMinorVersion uint32
|
||||||
|
dwBuildNumber uint32
|
||||||
|
dwPlatformId uint32
|
||||||
|
szCSDVersion [128]uint16
|
||||||
|
wServicePackMajor uint16
|
||||||
|
wServicePackMinor uint16
|
||||||
|
wSuiteMask uint16
|
||||||
|
wProductType byte
|
||||||
|
wReserved byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func _HIBYTE(wValue uint16) byte {
|
||||||
|
return byte(wValue >> 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _LOBYTE(wValue uint16) byte {
|
||||||
|
return byte(wValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
|
ntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||||
|
|
||||||
|
procVerSetConditionMask = kernel32.NewProc("VerSetConditionMask")
|
||||||
|
|
||||||
|
procRtlVerifyVersionInfo = ntdll.NewProc("RtlVerifyVersionInfo")
|
||||||
|
)
|
||||||
|
|
||||||
|
func _RtlVerifyVersionInfo(versionInfo *_OSVERSIONINFOEXW, typeMask uint32, conditionMask uint64) int32 {
|
||||||
|
var r uintptr
|
||||||
|
if unsafe.Sizeof(uintptr(0)) == unsafe.Sizeof(uint64(0)) {
|
||||||
|
r, _, _ = procRtlVerifyVersionInfo.Call(uintptr(unsafe.Pointer(versionInfo)), uintptr(typeMask), uintptr(conditionMask))
|
||||||
|
} else {
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "386":
|
||||||
|
r, _, _ = procRtlVerifyVersionInfo.Call(uintptr(unsafe.Pointer(versionInfo)), uintptr(typeMask), uintptr(conditionMask), uintptr(conditionMask>>32))
|
||||||
|
case "arm":
|
||||||
|
// Adjust the alignment for ARM.
|
||||||
|
r, _, _ = procRtlVerifyVersionInfo.Call(uintptr(unsafe.Pointer(versionInfo)), uintptr(typeMask), 0, uintptr(conditionMask), uintptr(conditionMask>>32))
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("goglfw: GOARCH=%s is not supported", runtime.GOARCH))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return int32(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _VerSetConditionMask(conditionMask uint64, typeMask uint32, condition byte) uint64 {
|
||||||
|
if unsafe.Sizeof(uintptr(0)) == unsafe.Sizeof(uint64(0)) {
|
||||||
|
r, _, _ := procVerSetConditionMask.Call(uintptr(conditionMask), uintptr(typeMask), uintptr(condition))
|
||||||
|
return uint64(r)
|
||||||
|
} else {
|
||||||
|
r1, r2, _ := procVerSetConditionMask.Call(uintptr(conditionMask), uintptr(conditionMask>>32), uintptr(typeMask), uintptr(condition))
|
||||||
|
return uint64(r1) | (uint64(r2) << 32)
|
||||||
|
}
|
||||||
|
}
|
87
internal/winver/winver_windows.go
Normal file
87
internal/winver/winver_windows.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 2023 The Ebitengine 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 winver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isWindowsVersionOrGreater(major, minor, sp uint16) bool {
|
||||||
|
osvi := _OSVERSIONINFOEXW{
|
||||||
|
dwMajorVersion: uint32(major),
|
||||||
|
dwMinorVersion: uint32(minor),
|
||||||
|
wServicePackMajor: sp,
|
||||||
|
}
|
||||||
|
osvi.dwOSVersionInfoSize = uint32(unsafe.Sizeof(osvi))
|
||||||
|
var mask uint32 = _VER_MAJORVERSION | _VER_MINORVERSION | _VER_SERVICEPACKMAJOR
|
||||||
|
cond := _VerSetConditionMask(0, _VER_MAJORVERSION, _VER_GREATER_EQUAL)
|
||||||
|
cond = _VerSetConditionMask(cond, _VER_MINORVERSION, _VER_GREATER_EQUAL)
|
||||||
|
cond = _VerSetConditionMask(cond, _VER_SERVICEPACKMAJOR, _VER_GREATER_EQUAL)
|
||||||
|
|
||||||
|
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
||||||
|
// latter lies unless the user knew to embed a non-default manifest
|
||||||
|
// announcing support for Windows 10 via supportedOS GUID
|
||||||
|
return _RtlVerifyVersionInfo(&osvi, mask, cond) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func isWindows10BuildOrGreater(build uint16) bool {
|
||||||
|
osvi := _OSVERSIONINFOEXW{
|
||||||
|
dwMajorVersion: 10,
|
||||||
|
dwMinorVersion: 0,
|
||||||
|
dwBuildNumber: uint32(build),
|
||||||
|
}
|
||||||
|
osvi.dwOSVersionInfoSize = uint32(unsafe.Sizeof(osvi))
|
||||||
|
var mask uint32 = _VER_MAJORVERSION | _VER_MINORVERSION | _VER_BUILDNUMBER
|
||||||
|
cond := _VerSetConditionMask(0, _VER_MAJORVERSION, _VER_GREATER_EQUAL)
|
||||||
|
cond = _VerSetConditionMask(cond, _VER_MINORVERSION, _VER_GREATER_EQUAL)
|
||||||
|
cond = _VerSetConditionMask(cond, _VER_BUILDNUMBER, _VER_GREATER_EQUAL)
|
||||||
|
|
||||||
|
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
||||||
|
// latter lies unless the user knew to embed a non-default manifest
|
||||||
|
// announcing support for Windows 10 via supportedOS GUID
|
||||||
|
return _RtlVerifyVersionInfo(&osvi, mask, cond) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsWindowsXPOrGreater() bool {
|
||||||
|
return isWindowsVersionOrGreater(uint16(_HIBYTE(_WIN32_WINNT_WINXP)), uint16(_LOBYTE(_WIN32_WINNT_WINXP)), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsWindowsVistaOrGreater() bool {
|
||||||
|
return isWindowsVersionOrGreater(uint16(_HIBYTE(_WIN32_WINNT_VISTA)), uint16(_LOBYTE(_WIN32_WINNT_VISTA)), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsWindows7OrGreater() bool {
|
||||||
|
return isWindowsVersionOrGreater(uint16(_HIBYTE(_WIN32_WINNT_WIN7)), uint16(_LOBYTE(_WIN32_WINNT_WIN7)), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsWindows8OrGreater() bool {
|
||||||
|
return isWindowsVersionOrGreater(uint16(_HIBYTE(_WIN32_WINNT_WIN8)), uint16(_LOBYTE(_WIN32_WINNT_WIN8)), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsWindows8Point1OrGreater() bool {
|
||||||
|
return isWindowsVersionOrGreater(uint16(_HIBYTE(_WIN32_WINNT_WINBLUE)), uint16(_LOBYTE(_WIN32_WINNT_WINBLUE)), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsWindows10OrGreater() bool {
|
||||||
|
return isWindows10BuildOrGreater(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsWindows10AnniversaryUpdateOrGreater() bool {
|
||||||
|
return isWindows10BuildOrGreater(14393)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsWindows10CreatorsUpdateOrGreater() bool {
|
||||||
|
return isWindows10BuildOrGreater(15063)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user