| // Copyright 2015 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| //go:build windows |
| // +build windows |
| |
| package windriver |
| |
| import ( |
| "fmt" |
| "image" |
| "sync" |
| "syscall" |
| "unsafe" |
| |
| "golang.org/x/exp/shiny/driver/internal/win32" |
| "golang.org/x/exp/shiny/screen" |
| ) |
| |
| var theScreen = &screenImpl{ |
| windows: make(map[syscall.Handle]*windowImpl), |
| } |
| |
| type screenImpl struct { |
| mu sync.Mutex |
| windows map[syscall.Handle]*windowImpl |
| } |
| |
| func (*screenImpl) NewBuffer(size image.Point) (screen.Buffer, error) { |
| // Buffer length must fit in BITMAPINFO.Header.SizeImage (uint32), as |
| // well as in Go slice length (int). It's easiest to be consistent |
| // between 32-bit and 64-bit, so we just use int32. |
| const ( |
| maxInt32 = 0x7fffffff |
| maxBufLen = maxInt32 |
| ) |
| if size.X < 0 || size.X > maxInt32 || size.Y < 0 || size.Y > maxInt32 || int64(size.X)*int64(size.Y)*4 > maxBufLen { |
| return nil, fmt.Errorf("windriver: invalid buffer size %v", size) |
| } |
| |
| hbitmap, bitvalues, err := mkbitmap(size) |
| if err != nil { |
| return nil, err |
| } |
| bufLen := 4 * size.X * size.Y |
| array := (*[maxBufLen]byte)(unsafe.Pointer(bitvalues)) |
| buf := (*array)[:bufLen:bufLen] |
| return &bufferImpl{ |
| hbitmap: hbitmap, |
| buf: buf, |
| rgba: image.RGBA{ |
| Pix: buf, |
| Stride: 4 * size.X, |
| Rect: image.Rectangle{Max: size}, |
| }, |
| size: size, |
| }, nil |
| } |
| |
| func (*screenImpl) NewTexture(size image.Point) (screen.Texture, error) { |
| return newTexture(size) |
| } |
| |
| func (s *screenImpl) NewWindow(opts *screen.NewWindowOptions) (screen.Window, error) { |
| w := &windowImpl{} |
| |
| var err error |
| w.hwnd, err = win32.NewWindow(opts) |
| if err != nil { |
| return nil, err |
| } |
| |
| s.mu.Lock() |
| s.windows[w.hwnd] = w |
| s.mu.Unlock() |
| |
| err = win32.ResizeClientRect(w.hwnd, opts) |
| if err != nil { |
| return nil, err |
| } |
| |
| win32.Show(w.hwnd) |
| return w, nil |
| } |