github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/exp/shiny/driver/windriver/screen.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build windows
     6  
     7  package windriver
     8  
     9  import (
    10  	"fmt"
    11  	"image"
    12  	"sync"
    13  	"unsafe"
    14  
    15  	"golang.org/x/exp/shiny/driver/internal/pump"
    16  	"golang.org/x/exp/shiny/driver/internal/win32"
    17  	"golang.org/x/exp/shiny/screen"
    18  )
    19  
    20  var theScreen = &screenImpl{
    21  	windows: make(map[win32.HWND]*windowImpl),
    22  }
    23  
    24  type screenImpl struct {
    25  	mu      sync.Mutex
    26  	windows map[win32.HWND]*windowImpl
    27  }
    28  
    29  func (*screenImpl) NewBuffer(size image.Point) (screen.Buffer, error) {
    30  	// Buffer length must fit in BITMAPINFO.Header.SizeImage (uint32), as
    31  	// well as in Go slice length (int). It's easiest to be consistent
    32  	// between 32-bit and 64-bit, so we just use int32.
    33  	const (
    34  		maxInt32  = 0x7fffffff
    35  		maxBufLen = maxInt32
    36  	)
    37  	if size.X < 0 || size.X > maxInt32 || size.Y < 0 || size.Y > maxInt32 || int64(size.X)*int64(size.Y)*4 > maxBufLen {
    38  		return nil, fmt.Errorf("windriver: invalid buffer size %v", size)
    39  	}
    40  
    41  	hbitmap, bitvalues, err := mkbitmap(int32(size.X), int32(size.Y))
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	bufLen := 4 * size.X * size.Y
    46  	array := (*[maxBufLen]byte)(unsafe.Pointer(bitvalues))
    47  	buf := (*array)[:bufLen:bufLen]
    48  	return &bufferImpl{
    49  		hbitmap: hbitmap,
    50  		buf:     buf,
    51  		rgba: image.RGBA{
    52  			Pix:    buf,
    53  			Stride: 4 * size.X,
    54  			Rect:   image.Rectangle{Max: size},
    55  		},
    56  		size:     size,
    57  		reusable: true,
    58  	}, nil
    59  }
    60  
    61  func (*screenImpl) NewTexture(size image.Point) (screen.Texture, error) {
    62  	return &textureImpl{}, nil
    63  }
    64  
    65  func (s *screenImpl) NewWindow(opts *screen.NewWindowOptions) (screen.Window, error) {
    66  	w := &windowImpl{
    67  		pump: pump.Make(),
    68  	}
    69  
    70  	var err error
    71  	w.hwnd, err = win32.NewWindow(opts)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	s.mu.Lock()
    77  	s.windows[w.hwnd] = w
    78  	s.mu.Unlock()
    79  
    80  	win32.Show(w.hwnd)
    81  	return w, nil
    82  }