window.go raw

   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  
  10  	"github.com/p9c/p9/pkg/gel/gio/gpu"
  11  	"github.com/p9c/p9/pkg/gel/gio/io/event"
  12  	"github.com/p9c/p9/pkg/gel/gio/io/pointer"
  13  	"github.com/p9c/p9/pkg/gel/gio/io/system"
  14  	"github.com/p9c/p9/pkg/gel/gio/unit"
  15  )
  16  
  17  type Size struct {
  18  	Width  unit.Value
  19  	Height unit.Value
  20  }
  21  
  22  type Options struct {
  23  	Size       *Size
  24  	MinSize    *Size
  25  	MaxSize    *Size
  26  	Title      *string
  27  	WindowMode *WindowMode
  28  }
  29  
  30  type WindowMode uint8
  31  
  32  const (
  33  	Windowed WindowMode = iota
  34  	Fullscreen
  35  )
  36  
  37  type FrameEvent struct {
  38  	system.FrameEvent
  39  
  40  	Sync bool
  41  }
  42  
  43  type Callbacks interface {
  44  	SetDriver(d Driver)
  45  	Event(e event.Event)
  46  }
  47  
  48  type Context interface {
  49  	API() gpu.API
  50  	Present() error
  51  	MakeCurrent() error
  52  	Release()
  53  	Lock()
  54  	Unlock()
  55  }
  56  
  57  // ErrDeviceLost is returned from Context.Present when
  58  // the underlying GPU device is gone and should be
  59  // recreated.
  60  var ErrDeviceLost = errors.New("GPU device lost")
  61  
  62  // Driver is the interface for the platform implementation
  63  // of a window.
  64  type Driver interface {
  65  	// SetAnimating sets the animation flag. When the window is animating,
  66  	// FrameEvents are delivered as fast as the display can handle them.
  67  	SetAnimating(anim bool)
  68  	// ShowTextInput updates the virtual keyboard state.
  69  	ShowTextInput(show bool)
  70  	NewContext() (Context, error)
  71  
  72  	// ReadClipboard requests the clipboard content.
  73  	ReadClipboard()
  74  	// WriteClipboard requests a clipboard write.
  75  	WriteClipboard(s string)
  76  
  77  	// Option processes option changes.
  78  	Option(opts *Options)
  79  
  80  	// SetCursor updates the current cursor to name.
  81  	SetCursor(name pointer.CursorName)
  82  
  83  	// Close the window.
  84  	Close()
  85  }
  86  
  87  type windowRendezvous struct {
  88  	in   chan windowAndOptions
  89  	out  chan windowAndOptions
  90  	errs chan error
  91  }
  92  
  93  type windowAndOptions struct {
  94  	window Callbacks
  95  	opts   *Options
  96  }
  97  
  98  func newWindowRendezvous() *windowRendezvous {
  99  	wr := &windowRendezvous{
 100  		in:   make(chan windowAndOptions),
 101  		out:  make(chan windowAndOptions),
 102  		errs: make(chan error),
 103  	}
 104  	go func() {
 105  		var main windowAndOptions
 106  		var out chan windowAndOptions
 107  		for {
 108  			select {
 109  			case w := <-wr.in:
 110  				var err error
 111  				if main.window != nil {
 112  					err = errors.New("multiple windows are not supported")
 113  				}
 114  				wr.errs <- err
 115  				main = w
 116  				out = wr.out
 117  			case out <- main:
 118  			}
 119  		}
 120  	}()
 121  	return wr
 122  }
 123