func handleUpload(hwnd win32.HWND, uMsg uint32, wParam, lParam uintptr) { id := wParam uploadsMu.Lock() u := uploads[id] delete(uploads, id) uploadsMu.Unlock() dc, err := win32.GetDC(hwnd) if err != nil { panic(err) // TODO handle errors } defer win32.ReleaseDC(hwnd, dc) u.src.preUpload(true) // TODO: adjust if dp is outside dst bounds, or sr is outside src bounds. err = blit(dc, _POINT{int32(u.dp.X), int32(u.dp.Y)}, u.src.hbitmap, &_RECT{ Left: int32(u.sr.Min.X), Top: int32(u.sr.Min.Y), Right: int32(u.sr.Max.X), Bottom: int32(u.sr.Max.Y), }) go func() { u.src.postUpload() close(u.completion) }() if err != nil { panic(err) // TODO handle errors } }
func fillSrc(hwnd win32.HWND, uMsg uint32, wParam, lParam uintptr) { dc, err := win32.GetDC(hwnd) if err != nil { panic(err) // TODO handle error? } defer win32.ReleaseDC(hwnd, dc) r := (*_RECT)(unsafe.Pointer(lParam)) color := _COLORREF(wParam) // COLORREF is 0x00BBGGRR; color is 0xAARRGGBB color = _RGB(byte((color >> 16)), byte((color >> 8)), byte(color)) brush, err := _CreateSolidBrush(color) if err != nil { panic(err) // TODO handle error } defer _DeleteObject(brush) err = _FillRect(dc, r, brush) if err != nil { panic(err) // TODO handle error } }
func fillOver(hwnd win32.HWND, uMsg uint32, wParam, lParam uintptr) { dc, err := win32.GetDC(hwnd) if err != nil { panic(err) // TODO handle error } defer win32.ReleaseDC(hwnd, dc) r := (*_RECT)(unsafe.Pointer(lParam)) color := _COLORREF(wParam) // AlphaBlend will stretch the input image (using StretchBlt's // COLORONCOLOR mode) to fill the output rectangle. Testing // this shows that the result appears to be the same as if we had // used a MxN bitmap instead. bitmap, bitvalues, err := mkbitmap(1, 1) if err != nil { panic(err) // TODO handle error } defer _DeleteObject(bitmap) // TODO handle error? *(*_COLORREF)(unsafe.Pointer(bitvalues)) = color if err = blend(dc, bitmap, r, 1, 1); err != nil { panic(err) // TODO handle error } }
func createEGLSurface(hwnd syscall.Handle, w *windowImpl) error { var displayAttribPlatforms = [][]eglInt{ // Default []eglInt{ _EGL_PLATFORM_ANGLE_TYPE_ANGLE, _EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE, _EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE, _EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE, _EGL_NONE, }, // Direct3D 11 []eglInt{ _EGL_PLATFORM_ANGLE_TYPE_ANGLE, _EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, _EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE, _EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE, _EGL_NONE, }, // Direct3D 9 []eglInt{ _EGL_PLATFORM_ANGLE_TYPE_ANGLE, _EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, _EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE, _EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE, _EGL_NONE, }, // Direct3D 11 with WARP // https://msdn.microsoft.com/en-us/library/windows/desktop/gg615082.aspx []eglInt{ _EGL_PLATFORM_ANGLE_TYPE_ANGLE, _EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, _EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, _EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, _EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE, _EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE, _EGL_NONE, }, } dc, err := win32.GetDC(hwnd) if err != nil { return fmt.Errorf("win32.GetDC failed: %v", err) } var display uintptr = _EGL_NO_DISPLAY for i, displayAttrib := range displayAttribPlatforms { lastTry := i == len(displayAttribPlatforms)-1 display, _, _ = eglGetPlatformDisplayEXT.Call( _EGL_PLATFORM_ANGLE_ANGLE, uintptr(dc), uintptr(unsafe.Pointer(&displayAttrib[0])), ) if display == _EGL_NO_DISPLAY { if !lastTry { continue } return fmt.Errorf("eglGetPlatformDisplayEXT failed: %v", eglErr()) } if ret, _, _ := eglInitialize.Call(display, 0, 0); ret == 0 { if !lastTry { continue } return fmt.Errorf("eglInitialize failed: %v", eglErr()) } } eglBindAPI.Call(_EGL_OPENGL_ES_API) if err := eglErr(); err != nil { return err } var numConfigs eglInt var config eglConfig ret, _, _ := eglChooseConfig.Call( display, uintptr(unsafe.Pointer(&rgb888[0])), uintptr(unsafe.Pointer(&config)), 1, uintptr(unsafe.Pointer(&numConfigs)), ) if ret == 0 { return fmt.Errorf("eglChooseConfig failed: %v", eglErr()) } if numConfigs <= 0 { return errors.New("eglChooseConfig found no valid config") } surface, _, _ := eglCreateWindowSurface.Call(display, uintptr(config), uintptr(hwnd), 0, 0) if surface == _EGL_NO_SURFACE { return fmt.Errorf("eglCreateWindowSurface failed: %v", eglErr()) } contextAttribs := [...]eglInt{ _EGL_CONTEXT_CLIENT_VERSION, 2, _EGL_NONE, } context, _, _ := eglCreateContext.Call( display, uintptr(config), _EGL_NO_CONTEXT, uintptr(unsafe.Pointer(&contextAttribs[0])), ) if context == _EGL_NO_CONTEXT { return fmt.Errorf("eglCreateContext failed: %v", eglErr()) } eglSwapInterval.Call(display, 1) w.ctx = ctxWin32{ ctx: context, display: display, surface: surface, } return nil }
func createEGLSurface(hwnd win32.HWND, w *windowImpl) error { displayAttrib := [...]eglInt{ _EGL_PLATFORM_ANGLE_TYPE_ANGLE, _EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE, _EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE, _EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE, _EGL_NONE, } dc, err := win32.GetDC(hwnd) if err != nil { return fmt.Errorf("win32.GetDC failed: %v", err) } display, _, _ := eglGetPlatformDisplayEXT.Call( _EGL_PLATFORM_ANGLE_ANGLE, uintptr(dc), uintptr(unsafe.Pointer(&displayAttrib)), ) if display == _EGL_NO_DISPLAY { return fmt.Errorf("eglGetPlatformDisplayEXT failed: %v", eglErr()) } if ret, _, _ := eglInitialize.Call(display, 0, 0); ret == 0 { return fmt.Errorf("eglInitialize failed: %v", eglErr()) } eglBindAPI.Call(_EGL_OPENGL_ES_API) if err := eglErr(); err != nil { return err } var numConfigs eglInt var config eglConfig ret, _, _ := eglChooseConfig.Call( display, uintptr(unsafe.Pointer(&rgb888[0])), uintptr(unsafe.Pointer(&config)), 1, uintptr(unsafe.Pointer(&numConfigs)), ) if ret == 0 { return fmt.Errorf("eglChooseConfig failed: %v", eglErr()) } if numConfigs <= 0 { return errors.New("eglChooseConfig found no valid config") } surface, _, _ := eglCreateWindowSurface.Call(display, uintptr(config), uintptr(hwnd), 0, 0) if surface == _EGL_NO_SURFACE { return fmt.Errorf("eglCreateWindowSurface failed: %v", eglErr()) } contextAttribs := [...]eglInt{ _EGL_CONTEXT_CLIENT_VERSION, 2, _EGL_NONE, } context, _, _ := eglCreateContext.Call( display, uintptr(config), _EGL_NO_CONTEXT, uintptr(unsafe.Pointer(&contextAttribs[0])), ) if context == _EGL_NO_CONTEXT { return fmt.Errorf("eglCreateContext failed: %v", eglErr()) } eglSwapInterval.Call(display, 1) w.ctx = ctxWin32{ ctx: context, display: display, surface: surface, } return nil }