This repository has been archived on 2023-08-08. You can view files and clone it, but cannot push or open issues or pull requests.
tomo-old/backends/x/x.go

120 lines
2.5 KiB
Go
Raw Normal View History

2023-01-08 23:03:19 -07:00
package x
import "git.tebibyte.media/sashakoshka/tomo"
import "github.com/jezek/xgbutil"
import "github.com/jezek/xgb/xproto"
import "github.com/jezek/xgbutil/xevent"
// Backend is an instance of an X backend.
type Backend struct {
connection *xgbutil.XUtil
doChannel chan(func ())
modifierMasks struct {
capsLock uint16
shiftLock uint16
numLock uint16
modeSwitch uint16
alt uint16
meta uint16
super uint16
hyper uint16
}
2023-03-30 23:06:29 -06:00
theme tomo.Theme
config tomo.Config
2023-02-02 23:35:59 -07:00
windows map[xproto.Window] *window
open bool
2023-01-08 23:03:19 -07:00
}
// NewBackend instantiates an X backend.
func NewBackend () (output tomo.Backend, err error) {
backend := &Backend {
2023-03-30 23:06:29 -06:00
windows: map[xproto.Window] *window { },
2023-03-27 18:44:39 -06:00
doChannel: make(chan func (), 32),
2023-03-30 23:06:29 -06:00
open: true,
2023-01-08 23:03:19 -07:00
}
// connect to X
backend.connection, err = xgbutil.NewConn()
if err != nil { return }
backend.initializeKeymapInformation()
output = backend
return
}
// Run runs the backend's event loop. This method will not exit until Stop() is
// called, or the backend experiences a fatal error.
func (backend *Backend) Run () (err error) {
backend.assert()
pingBefore,
pingAfter,
pingQuit := xevent.MainPing(backend.connection)
for {
select {
case <- pingBefore:
<- pingAfter
2023-01-08 23:03:19 -07:00
case callback := <- backend.doChannel:
callback()
case <- pingQuit:
return
2023-01-08 23:03:19 -07:00
}
}
}
// Stop gracefully closes the connection and stops the event loop.
func (backend *Backend) Stop () {
backend.assert()
if !backend.open { return }
backend.open = false
toClose := []*window { }
2023-01-08 23:03:19 -07:00
for _, window := range backend.windows {
toClose = append(toClose, window)
}
for _, window := range toClose {
2023-01-08 23:03:19 -07:00
window.Close()
}
xevent.Quit(backend.connection)
backend.connection.Conn().Close()
}
// Do executes the specified callback within the main thread as soon as
// possible. This function can be safely called from other threads.
func (backend *Backend) Do (callback func ()) {
backend.assert()
backend.doChannel <- callback
}
2023-02-02 23:35:59 -07:00
// SetTheme sets the theme of all open windows.
2023-03-30 23:06:29 -06:00
func (backend *Backend) SetTheme (theme tomo.Theme) {
2023-02-02 23:35:59 -07:00
backend.assert()
backend.theme = theme
for _, window := range backend.windows {
window.SetTheme(theme)
}
}
// SetConfig sets the configuration of all open windows.
2023-03-30 23:06:29 -06:00
func (backend *Backend) SetConfig (config tomo.Config) {
2023-02-02 23:35:59 -07:00
backend.assert()
backend.config = config
for _, window := range backend.windows {
window.SetConfig(config)
}
}
2023-01-08 23:03:19 -07:00
func (backend *Backend) assert () {
if backend == nil { panic("nil backend") }
}
func init () {
tomo.RegisterBackend(NewBackend)
}