github.com/cybriq/giocore@v0.0.7-0.20210703034601-cfb9cb5f3900/app/internal/wm/window.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  // package wm implements platform specific windows
     4  // and GPU contexts.
     5  package wm
     6  
     7  import (
     8  	"errors"
     9  	"github.com/cybriq/giocore/io/key"
    10  	"image/color"
    11  
    12  	"github.com/cybriq/giocore/gpu"
    13  	"github.com/cybriq/giocore/io/event"
    14  	"github.com/cybriq/giocore/io/pointer"
    15  	"github.com/cybriq/giocore/io/system"
    16  	"github.com/cybriq/giocore/unit"
    17  )
    18  
    19  type Size struct {
    20  	Width  unit.Value
    21  	Height unit.Value
    22  }
    23  
    24  type Options struct {
    25  	Size            *Size
    26  	MinSize         *Size
    27  	MaxSize         *Size
    28  	Title           *string
    29  	WindowMode      *WindowMode
    30  	StatusColor     *color.NRGBA
    31  	NavigationColor *color.NRGBA
    32  	Orientation     *Orientation
    33  	CustomRenderer  bool
    34  }
    35  
    36  type WakeupEvent struct{}
    37  
    38  type WindowMode uint8
    39  
    40  const (
    41  	Windowed WindowMode = iota
    42  	Fullscreen
    43  )
    44  
    45  type Orientation uint8
    46  
    47  const (
    48  	AnyOrientation Orientation = iota
    49  	LandscapeOrientation
    50  	PortraitOrientation
    51  )
    52  
    53  type FrameEvent struct {
    54  	system.FrameEvent
    55  
    56  	Sync bool
    57  }
    58  
    59  type Callbacks interface {
    60  	SetDriver(d Driver)
    61  	Event(e event.Event)
    62  	// Func runs a function during an Event. This is required for platforms
    63  	// that require coordination between the rendering goroutine and the system
    64  	// main thread.
    65  	Run(f func())
    66  }
    67  
    68  type Context interface {
    69  	API() gpu.API
    70  	Present() error
    71  	MakeCurrent() error
    72  	Refresh() error
    73  	Release()
    74  	Lock()
    75  	Unlock()
    76  }
    77  
    78  // ErrDeviceLost is returned from Context.Present when
    79  // the underlying GPU device is gone and should be
    80  // recreated.
    81  var ErrDeviceLost = errors.New("GPU device lost")
    82  
    83  // Driver is the interface for the platform implementation
    84  // of a window.
    85  type Driver interface {
    86  	// SetAnimating sets the animation flag. When the window is animating,
    87  	// FrameEvents are delivered as fast as the display can handle them.
    88  	SetAnimating(anim bool)
    89  
    90  	// ShowTextInput updates the virtual keyboard state.
    91  	ShowTextInput(show bool)
    92  
    93  	SetInputHint(mode key.InputHint)
    94  
    95  	NewContext() (Context, error)
    96  
    97  	// ReadClipboard requests the clipboard content.
    98  	ReadClipboard()
    99  	// WriteClipboard requests a clipboard write.
   100  	WriteClipboard(s string)
   101  
   102  	// Option processes option changes.
   103  	Option(opts *Options)
   104  
   105  	// SetCursor updates the current cursor to name.
   106  	SetCursor(name pointer.CursorName)
   107  
   108  	// Close the window.
   109  	Close()
   110  	// Wakeup wakes up the event loop and sends a WakeupEvent.
   111  	Wakeup()
   112  }
   113  
   114  type windowRendezvous struct {
   115  	in   chan windowAndOptions
   116  	out  chan windowAndOptions
   117  	errs chan error
   118  }
   119  
   120  type windowAndOptions struct {
   121  	window Callbacks
   122  	opts   *Options
   123  }
   124  
   125  func newWindowRendezvous() *windowRendezvous {
   126  	wr := &windowRendezvous{
   127  		in:   make(chan windowAndOptions),
   128  		out:  make(chan windowAndOptions),
   129  		errs: make(chan error),
   130  	}
   131  	go func() {
   132  		var main windowAndOptions
   133  		var out chan windowAndOptions
   134  		for {
   135  			select {
   136  			case w := <-wr.in:
   137  				var err error
   138  				if main.window != nil {
   139  					err = errors.New("multiple windows are not supported")
   140  				}
   141  				wr.errs <- err
   142  				main = w
   143  				out = wr.out
   144  			case out <- main:
   145  			}
   146  		}
   147  	}()
   148  	return wr
   149  }
   150  
   151  func (_ WakeupEvent) ImplementsEvent() {}