mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/graphicsdriver/opengl, internal/uidriver/glfw: treat Win32 API errors correctly
The returned errors from syscall.Syscall* and windows.LazyProc.Call come from GetLastError. The value of GetLastError is not reliable when the function succeeds. This change fixes the usages of error values. The error value is now used only when the API explicitly fails.
This commit is contained in:
parent
b3e8d5d7ae
commit
84e53d4c61
@ -10,8 +10,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
opengl32 = windows.NewLazySystemDLL("opengl32")
|
||||
wglGetProcAddress = opengl32.NewProc("wglGetProcAddress")
|
||||
opengl32 = windows.NewLazySystemDLL("opengl32")
|
||||
procWglGetProcAddress = opengl32.NewProc("wglGetProcAddress")
|
||||
)
|
||||
|
||||
func getProcAddress(namea string) uintptr {
|
||||
@ -20,13 +20,13 @@ func getProcAddress(namea string) uintptr {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
r, _, err := wglGetProcAddress.Call(uintptr(unsafe.Pointer(cname)))
|
||||
if err != nil && err != windows.ERROR_SUCCESS && err != windows.ERROR_PROC_NOT_FOUND {
|
||||
panic(fmt.Sprintf("gl: wglGetProcAddress failed: %s", err.Error()))
|
||||
}
|
||||
r, _, err := procWglGetProcAddress.Call(uintptr(unsafe.Pointer(cname)))
|
||||
if r != 0 {
|
||||
return r
|
||||
}
|
||||
if err != nil && err != windows.ERROR_SUCCESS && err != windows.ERROR_PROC_NOT_FOUND {
|
||||
panic(fmt.Sprintf("gl: wglGetProcAddress failed: %s", err.Error()))
|
||||
}
|
||||
|
||||
p := opengl32.NewProc(namea)
|
||||
if err := p.Find(); err != nil {
|
||||
|
@ -29,71 +29,48 @@ var (
|
||||
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
user32 = windows.NewLazySystemDLL("user32.dll")
|
||||
|
||||
getCurrentProcessIdProc = kernel32.NewProc("GetCurrentProcessId")
|
||||
getConsoleWindowProc = kernel32.NewProc("GetConsoleWindow")
|
||||
freeConsoleWindowProc = kernel32.NewProc("FreeConsole")
|
||||
getWindowThreadProcessIdProc = user32.NewProc("GetWindowThreadProcessId")
|
||||
procFreeConsoleWindow = kernel32.NewProc("FreeConsole")
|
||||
procGetCurrentProcessId = kernel32.NewProc("GetCurrentProcessId")
|
||||
procGetConsoleWindow = kernel32.NewProc("GetConsoleWindow")
|
||||
procGetWindowThreadProcessId = user32.NewProc("GetWindowThreadProcessId")
|
||||
)
|
||||
|
||||
func getCurrentProcessId() (uint32, error) {
|
||||
r, _, e := getCurrentProcessIdProc.Call()
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
return 0, fmt.Errorf("ui: GetCurrentProcessId failed: %w", e)
|
||||
}
|
||||
return uint32(r), nil
|
||||
}
|
||||
|
||||
func getWindowThreadProcessId(hwnd uintptr) (uint32, error) {
|
||||
pid := uint32(0)
|
||||
r, _, e := getWindowThreadProcessIdProc.Call(hwnd, uintptr(unsafe.Pointer(&pid)))
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
return 0, fmt.Errorf("ui: GetWindowThreadProcessId failed: %w", e)
|
||||
}
|
||||
if r == 0 {
|
||||
return 0, fmt.Errorf("ui: GetWindowThreadProcessId returned 0")
|
||||
}
|
||||
return pid, nil
|
||||
}
|
||||
|
||||
func getConsoleWindow() (uintptr, error) {
|
||||
r, _, e := getConsoleWindowProc.Call()
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
return 0, fmt.Errorf("ui: GetConsoleWindow failed: %w", e)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func freeConsole() error {
|
||||
if _, _, e := freeConsoleWindowProc.Call(); e != nil && e != windows.ERROR_SUCCESS {
|
||||
return fmt.Errorf("ui: FreeConsole failed: %w", e)
|
||||
r, _, e := procFreeConsoleWindow.Call()
|
||||
if r == 0 {
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
return fmt.Errorf("glfw: FreeConsole failed: %w", e)
|
||||
}
|
||||
return fmt.Errorf("glfw: FreeConsole returned 0")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getCurrentProcessId() uint32 {
|
||||
r, _, _ := procGetCurrentProcessId.Call()
|
||||
return uint32(r)
|
||||
}
|
||||
|
||||
func getConsoleWindow() windows.HWND {
|
||||
r, _, _ := procGetConsoleWindow.Call()
|
||||
return windows.HWND(r)
|
||||
}
|
||||
|
||||
func getWindowThreadProcessId(hwnd windows.HWND) (tid, pid uint32) {
|
||||
r, _, _ := procGetWindowThreadProcessId.Call(uintptr(hwnd), uintptr(unsafe.Pointer(&pid)))
|
||||
tid = uint32(r)
|
||||
return
|
||||
}
|
||||
|
||||
// hideConsoleWindowOnWindows will hide the console window that is showing when
|
||||
// compiling on Windows without specifying the '-ldflags "-Hwindowsgui"' flag.
|
||||
func hideConsoleWindowOnWindows() {
|
||||
pid, err := getCurrentProcessId()
|
||||
if err != nil {
|
||||
// Ignore errors because:
|
||||
// 1. It is not critical if the console can't be hid.
|
||||
// 2. There is nothing to do when errors happen.
|
||||
return
|
||||
}
|
||||
w, err := getConsoleWindow()
|
||||
if err != nil {
|
||||
// Ignore errors
|
||||
return
|
||||
}
|
||||
pid := getCurrentProcessId()
|
||||
// Get the process ID of the console's creator.
|
||||
cpid, err := getWindowThreadProcessId(w)
|
||||
if err != nil {
|
||||
// Ignore errors
|
||||
return
|
||||
}
|
||||
_, cpid := getWindowThreadProcessId(getConsoleWindow())
|
||||
if pid == cpid {
|
||||
// The current process created its own console. Hide this.
|
||||
// Ignore error
|
||||
// Ignore error.
|
||||
freeConsole()
|
||||
}
|
||||
}
|
||||
|
@ -52,40 +52,34 @@ var (
|
||||
procGetMonitorInfoW = user32.NewProc("GetMonitorInfoW")
|
||||
)
|
||||
|
||||
func getSystemMetrics(nIndex int) (int, error) {
|
||||
func getSystemMetrics(nIndex int) (int32, error) {
|
||||
r, _, e := procGetSystemMetrics.Call(uintptr(nIndex))
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
return 0, fmt.Errorf("ui: GetSystemMetrics failed: error code: %w", e)
|
||||
}
|
||||
return int(r), nil
|
||||
}
|
||||
|
||||
func getForegroundWindow() (uintptr, error) {
|
||||
r, _, e := procGetForegroundWindow.Call()
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
return 0, fmt.Errorf("ui: GetForegroundWindow failed: error code: %w", e)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func monitorFromWindow(hwnd uintptr, dwFlags uint32) (uintptr, error) {
|
||||
r, _, e := procMonitorFromWindow.Call(hwnd, uintptr(dwFlags))
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
return 0, fmt.Errorf("ui: MonitorFromWindow failed: error code: %w", e)
|
||||
}
|
||||
if r == 0 {
|
||||
return 0, fmt.Errorf("ui: MonitorFromWindow failed: returned value: %d", r)
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
return 0, fmt.Errorf("glfw: GetSystemMetrics failed: error code: %w", e)
|
||||
}
|
||||
return 0, fmt.Errorf("glfw: GetSystemMetrics returned 0")
|
||||
}
|
||||
return r, nil
|
||||
return int32(r), nil
|
||||
}
|
||||
|
||||
func getForegroundWindow() windows.HWND {
|
||||
r, _, _ := procGetForegroundWindow.Call()
|
||||
return windows.HWND(r)
|
||||
}
|
||||
|
||||
func monitorFromWindow(hwnd windows.HWND, dwFlags uint32) uintptr {
|
||||
r, _, _ := procMonitorFromWindow.Call(uintptr(hwnd), uintptr(dwFlags))
|
||||
return r
|
||||
}
|
||||
|
||||
func getMonitorInfoW(hMonitor uintptr, lpmi *monitorInfo) error {
|
||||
r, _, e := procGetMonitorInfoW.Call(hMonitor, uintptr(unsafe.Pointer(lpmi)))
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
return fmt.Errorf("ui: GetMonitorInfoW failed: error code: %w", e)
|
||||
}
|
||||
if r == 0 {
|
||||
return fmt.Errorf("ui: GetMonitorInfoW failed: returned value: %d", r)
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
return fmt.Errorf("glfw: GetMonitorInfoW failed: error code: %w", e)
|
||||
}
|
||||
return fmt.Errorf("glfw: GetMonitorInfoW failed: returned 0")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -119,18 +113,15 @@ func (u *UserInterface) adjustWindowPosition(x, y int) (int, int) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if y < my+t {
|
||||
y = my + t
|
||||
if y < my+int(t) {
|
||||
y = my + int(t)
|
||||
}
|
||||
return x, y
|
||||
}
|
||||
|
||||
func initialMonitorByOS() *glfw.Monitor {
|
||||
// Get the foreground window, that is common among multiple processes.
|
||||
w, err := getForegroundWindow()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w := getForegroundWindow()
|
||||
if w == 0 {
|
||||
// GetForegroundWindow can return null according to the document.
|
||||
return nil
|
||||
@ -139,15 +130,15 @@ func initialMonitorByOS() *glfw.Monitor {
|
||||
}
|
||||
|
||||
func currentMonitorByOS(w *glfw.Window) *glfw.Monitor {
|
||||
return monitorFromWin32Window(w.GetWin32Window())
|
||||
return monitorFromWin32Window(windows.HWND(w.GetWin32Window()))
|
||||
}
|
||||
|
||||
func monitorFromWin32Window(w uintptr) *glfw.Monitor {
|
||||
func monitorFromWin32Window(w windows.HWND) *glfw.Monitor {
|
||||
// Get the current monitor by the window handle instead of the window position. It is because the window
|
||||
// position is not relaiable in some cases e.g. when the window is put across multiple monitors.
|
||||
|
||||
m, err := monitorFromWindow(w, monitorDefaultToNearest)
|
||||
if err != nil {
|
||||
m := monitorFromWindow(w, monitorDefaultToNearest)
|
||||
if m == 0 {
|
||||
// monitorFromWindow can return error on Wine. Ignore this.
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user