mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +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
|
||||
_UNICODE_NOCHAR = 0xffff
|
||||
_USER_DEFAULT_SCREEN_DPI = 96
|
||||
_VER_BUILDNUMBER = 0x00000004
|
||||
_VER_GREATER_EQUAL = 3
|
||||
_VER_MAJORVERSION = 0x00000002
|
||||
_VER_MINORVERSION = 0x00000001
|
||||
_VER_SERVICEPACKMAJOR = 0x00000020
|
||||
_VERTSIZE = 6
|
||||
_VK_ADD = 0x6B
|
||||
_VK_CAPITAL = 0x14
|
||||
@ -262,11 +257,6 @@ const (
|
||||
_WGL_TRANSPARENT_INDEX_VALUE_ARB = 0x203B
|
||||
_WGL_TRANSPARENT_RED_VALUE_ARB = 0x2037
|
||||
_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_CHAR = 0x0102
|
||||
_WM_CLOSE = 0x0010
|
||||
@ -387,18 +377,11 @@ func _GET_XBUTTON_WPARAM(wParam _WPARAM) uint16 {
|
||||
func _GET_Y_LPARAM(lp _LPARAM) int {
|
||||
return int(_HIWORD(uint32(lp)))
|
||||
}
|
||||
func _HIBYTE(wValue uint16) byte {
|
||||
return byte(wValue >> 8)
|
||||
}
|
||||
|
||||
func _HIWORD(dwValue uint32) uint16 {
|
||||
return uint16(dwValue >> 16)
|
||||
}
|
||||
|
||||
func _LOBYTE(wValue uint16) byte {
|
||||
return byte(wValue)
|
||||
}
|
||||
|
||||
func _LOWORD(dwValue uint32) uint16 {
|
||||
return uint16(dwValue)
|
||||
}
|
||||
@ -590,20 +573,6 @@ type _MSG struct {
|
||||
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 {
|
||||
nSize uint16
|
||||
nVersion uint16
|
||||
@ -722,7 +691,6 @@ var (
|
||||
dwmapi = windows.NewLazySystemDLL("dwmapi.dll")
|
||||
gdi32 = windows.NewLazySystemDLL("gdi32.dll")
|
||||
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
ntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
opengl32 = windows.NewLazySystemDLL("opengl32.dll")
|
||||
shcore = windows.NewLazySystemDLL("shcore.dll")
|
||||
shell32 = windows.NewLazySystemDLL("shell32.dll")
|
||||
@ -749,9 +717,6 @@ var (
|
||||
procTlsFree = kernel32.NewProc("TlsFree")
|
||||
procTlsGetValue = kernel32.NewProc("TlsGetValue")
|
||||
procTlsSetValue = kernel32.NewProc("TlsSetValue")
|
||||
procVerSetConditionMask = kernel32.NewProc("VerSetConditionMask")
|
||||
|
||||
procRtlVerifyVersionInfo = ntdll.NewProc("RtlVerifyVersionInfo")
|
||||
|
||||
procWGLCreateContext = opengl32.NewProc("wglCreateContext")
|
||||
procWGLDeleteContext = opengl32.NewProc("wglDeleteContext")
|
||||
@ -1522,24 +1487,6 @@ func _ReleaseDC(hWnd windows.HWND, hDC _HDC) int32 {
|
||||
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 {
|
||||
r, _, e := procScreenToClient.Call(uintptr(hWnd), uintptr(unsafe.Pointer(lpPoint)))
|
||||
if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) {
|
||||
@ -1777,16 +1724,6 @@ func _UnregisterDeviceNotification(handle _HDEVNOTIFY) error {
|
||||
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 {
|
||||
r, _, e := procWaitMessage.Call()
|
||||
if int32(r) == 0 && !errors.Is(e, windows.ERROR_SUCCESS) {
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"golang.org/x/sys/windows"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/winver"
|
||||
)
|
||||
|
||||
func findPixelFormatAttribValue(attribs []int32, values []int32, attrib int32) int32 {
|
||||
@ -230,9 +231,9 @@ func makeContextCurrentWGL(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+
|
||||
enabled := _IsWindows8OrGreater()
|
||||
enabled := winver.IsWindows8OrGreater()
|
||||
|
||||
if !enabled {
|
||||
var err error
|
||||
@ -266,9 +267,9 @@ func swapIntervalWGL(interval int) error {
|
||||
|
||||
window.context.platform.interval = interval
|
||||
|
||||
if window.monitor == nil && _IsWindowsVistaOrGreater() {
|
||||
if window.monitor == nil && winver.IsWindowsVistaOrGreater() {
|
||||
// DWM Composition is always enabled on Win8+
|
||||
enabled := _IsWindows8OrGreater()
|
||||
enabled := winver.IsWindows8OrGreater()
|
||||
|
||||
if !enabled {
|
||||
e, err := _DwmIsCompositionEnabled()
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"golang.org/x/sys/windows"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/winver"
|
||||
)
|
||||
|
||||
func createKeyTables() {
|
||||
@ -238,41 +239,6 @@ func createHelperWindow() error {
|
||||
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 {
|
||||
// Changing the foreground lock timeout was removed from the original code.
|
||||
// See https://github.com/glfw/glfw/commit/58b48a3a00d9c2a5ca10cc23069a71d8773cc7a4
|
||||
@ -286,17 +252,17 @@ func platformInit() error {
|
||||
createKeyTables()
|
||||
updateKeyNamesWin32()
|
||||
|
||||
if isWindows10CreatorsUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10CreatorsUpdateOrGreater() {
|
||||
if !microsoftgdk.IsXbox() {
|
||||
// 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.
|
||||
_ = _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)) {
|
||||
return err
|
||||
}
|
||||
} else if _IsWindowsVistaOrGreater() {
|
||||
} else if winver.IsWindowsVistaOrGreater() {
|
||||
_SetProcessDPIAware()
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"golang.org/x/sys/windows"
|
||||
|
||||
"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 */ {
|
||||
@ -217,7 +218,7 @@ func (m *Monitor) restoreVideoModeWin32() {
|
||||
func getMonitorContentScaleWin32(handle _HMONITOR) (xscale, yscale float32, err error) {
|
||||
var xdpi, ydpi uint32
|
||||
|
||||
if _IsWindows8Point1OrGreater() {
|
||||
if winver.IsWindows8Point1OrGreater() {
|
||||
var err error
|
||||
xdpi, ydpi, err = _GetDpiForMonitor(handle, _MDT_EFFECTIVE_DPI)
|
||||
if err != nil {
|
||||
|
@ -5,7 +5,9 @@
|
||||
|
||||
package goglfw
|
||||
|
||||
import "golang.org/x/sys/windows"
|
||||
import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
_GLFW_WNDCLASSNAME = "GLFW30"
|
||||
@ -96,31 +98,3 @@ type platformLibraryContextState struct {
|
||||
ARB_create_context_no_error 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"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/winver"
|
||||
)
|
||||
|
||||
func (w *Window) getWindowStyle() uint32 {
|
||||
@ -137,7 +138,7 @@ func getFullWindowSize(style uint32, exStyle uint32, contentWidth, contentHeight
|
||||
right: int32(contentWidth),
|
||||
bottom: int32(contentHeight),
|
||||
}
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
if err := _AdjustWindowRectExForDpi(&rect, style, false, exStyle, dpi); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
@ -153,7 +154,7 @@ func (w *Window) applyAspectRatio(edge int, area *_RECT) error {
|
||||
ratio := float32(w.numer) / float32(w.denom)
|
||||
|
||||
var dpi uint32 = _USER_DEFAULT_SCREEN_DPI
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
dpi = _GetDpiForWindow(w.platform.handle)
|
||||
}
|
||||
|
||||
@ -343,7 +344,7 @@ func (w *Window) updateWindowStyles() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
if err := _AdjustWindowRectExForDpi(&rect, style, false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -368,7 +369,7 @@ func (w *Window) updateWindowStyles() error {
|
||||
}
|
||||
|
||||
func (w *Window) updateFramebufferTransparency() error {
|
||||
if !_IsWindowsVistaOrGreater() {
|
||||
if !winver.IsWindowsVistaOrGreater() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -382,7 +383,7 @@ func (w *Window) updateFramebufferTransparency() error {
|
||||
}
|
||||
|
||||
var opaque bool
|
||||
if !_IsWindows8OrGreater() {
|
||||
if !winver.IsWindows8OrGreater() {
|
||||
_, opaque, err = _DwmGetColorizationColor()
|
||||
if err != nil {
|
||||
// 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)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -473,7 +474,7 @@ func (w *Window) acquireMonitor() error {
|
||||
|
||||
// HACK: When mouse trails are enabled the cursor becomes invisible when
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -504,7 +505,7 @@ func (w *Window) releaseMonitor() error {
|
||||
_SetThreadExecutionState(_ES_CONTINUOUS)
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
@ -546,7 +547,7 @@ func (w *Window) maximizeWindowManually() error {
|
||||
return err
|
||||
}
|
||||
exStyle := uint32(s)
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
dpi := _GetDpiForWindow(w.platform.handle)
|
||||
if err := _AdjustWindowRectExForDpi(&rect, style, false, exStyle, dpi); err != nil {
|
||||
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
|
||||
switch uMsg {
|
||||
case _WM_NCCREATE:
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
cs := (*_CREATESTRUCTW)(unsafe.Pointer(lParam))
|
||||
wndconfig := (*wndconfig)(cs.lpCreateParams)
|
||||
|
||||
@ -1062,7 +1063,7 @@ func windowProc(hWnd windows.HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM)
|
||||
break
|
||||
}
|
||||
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
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
|
||||
if isWindows10CreatorsUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10CreatorsUpdateOrGreater() {
|
||||
var source, target _RECT
|
||||
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
|
||||
// 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))
|
||||
if err := _SetWindowPos(window.platform.handle, _HWND_TOP,
|
||||
suggested.left,
|
||||
@ -1244,7 +1245,7 @@ func (w *Window) createNativeWindow(wndconfig *wndconfig, fbconfig *fbconfig) er
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@ -1291,7 +1292,7 @@ func (w *Window) createNativeWindow(wndconfig *wndconfig, fbconfig *fbconfig) er
|
||||
return err
|
||||
}
|
||||
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
if err := _AdjustWindowRectExForDpi(&rect, style, false, exStyle, _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1577,7 +1578,7 @@ func (w *Window) platformSetWindowPos(xpos, ypos int) error {
|
||||
right: int32(xpos),
|
||||
bottom: int32(ypos),
|
||||
}
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1619,7 +1620,7 @@ func (w *Window) platformSetWindowSize(width, height int) error {
|
||||
bottom: int32(height),
|
||||
}
|
||||
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1688,7 +1689,7 @@ func (w *Window) platformGetWindowFrameSize() (left, top, right, bottom int, err
|
||||
right: int32(width),
|
||||
bottom: int32(height),
|
||||
}
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||
return 0, 0, 0, 0, err
|
||||
}
|
||||
@ -1770,7 +1771,7 @@ func (w *Window) platformSetWindowMonitor(monitor *Monitor, xpos, ypos, width, h
|
||||
right: int32(xpos + width),
|
||||
bottom: int32(ypos + height),
|
||||
}
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(), false, w.getWindowExStyle(), _GetDpiForWindow(w.platform.handle)); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1853,7 +1854,7 @@ func (w *Window) platformSetWindowMonitor(monitor *Monitor, xpos, ypos, width, h
|
||||
right: int32(xpos + width),
|
||||
bottom: int32(ypos + height),
|
||||
}
|
||||
if isWindows10AnniversaryUpdateOrGreaterWin32() {
|
||||
if winver.IsWindows10AnniversaryUpdateOrGreater() {
|
||||
if err := _AdjustWindowRectExForDpi(&rect, w.getWindowStyle(),
|
||||
false, w.getWindowExStyle(),
|
||||
_GetDpiForWindow(w.platform.handle)); err != nil {
|
||||
@ -1926,7 +1927,7 @@ func (w *Window) platformFramebufferTransparent() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if !_IsWindowsVistaOrGreater() {
|
||||
if !winver.IsWindowsVistaOrGreater() {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -1935,7 +1936,7 @@ func (w *Window) platformFramebufferTransparent() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if !_IsWindows8OrGreater() {
|
||||
if !winver.IsWindows8OrGreater() {
|
||||
// HACK: Disable framebuffer transparency on Windows 7 when the
|
||||
// colorization color is opaque, because otherwise the window
|
||||
// contents is blended additively with the previous frame instead
|
||||
|
@ -16,7 +16,6 @@ package directx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
@ -24,13 +23,6 @@ import (
|
||||
|
||||
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
|
||||
|
||||
func (h handleError) Error() string {
|
||||
@ -48,33 +40,13 @@ func boolToUintptr(v bool) uintptr {
|
||||
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
|
||||
|
||||
var (
|
||||
// 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")
|
||||
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
ntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
|
||||
procRegisterAppStateChangeNotification = appnotify.NewProc("RegisterAppStateChangeNotification")
|
||||
|
||||
procVerSetConditionMask = kernel32.NewProc("VerSetConditionMask")
|
||||
|
||||
procRtlVerifyVersionInfo = ntdll.NewProc("RtlVerifyVersionInfo")
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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/microsoftgdk"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/winver"
|
||||
)
|
||||
|
||||
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.
|
||||
// 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.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