package tomo import "sync" import "image" import "git.tebibyte.media/tomo/tomo/canvas" // TODO this really sucks. It might be a good idea to have Do be the entry point // for every off-thread call, and Stop should just call backend.Stop within // backend.Do. This is because Do is a queue and is not vulnerable to recursive // locking. var stopping bool var stoppingLock sync.Mutex func isStopping () bool { stoppingLock.Lock() defer stoppingLock.Unlock() return stopping } func setStopping (is bool) { stoppingLock.Lock() defer stoppingLock.Unlock() stopping = is } // Stop stops the currently running Backend. func Stop () { if isStopping() { return } setStopping(true) backendLock.Lock() defer backendLock.Unlock() if backend == nil { return } backend.Stop() backend = nil setStopping(false) } // Do performs a callback function in the event loop thread as soon as possible. func Do (callback func ()) { backendLock.Lock() defer backendLock.Unlock() if backend != nil { backend.Do(callback) } } // NewWindow creates and returns a Window within the specified bounds on screen. func NewWindow (kind WindowKind, bounds image.Rectangle) (Window, error) { assertBackend() return backend.NewWindow(kind, bounds) } // NewBox creates and returns a basic Box. func NewBox () Box { assertBackend() return backend.NewBox() } // NewTextBox creates and returns a Box that can display text. func NewTextBox () TextBox { assertBackend() return backend.NewTextBox() } // NewCanvasBox creates and returns a Box that can display custom graphics. func NewCanvasBox () CanvasBox { assertBackend() return backend.NewCanvasBox() } // NewContainerBox creates and returns a Box that can contain other boxes. func NewContainerBox () ContainerBox { assertBackend() return backend.NewContainerBox() } // NewTexture creates a new canvas.Texture from an image. When no longer in use, // it must be freed using Close(). func NewTexture (source image.Image) canvas.TextureCloser { assertBackend() return backend.NewTexture(source) } // NewCanvas creates a new canvas with the specified bounds. When no longer in // use, it must be freed using Close(). func NewCanvas (bounds image.Rectangle) canvas.CanvasCloser { assertBackend() return backend.NewCanvas(bounds) }