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
2023-01-09 01:03:19 -05:00

86 lines
1.8 KiB
Go

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
}
windows map[xproto.Window] *Window
}
// NewBackend instantiates an X backend.
func NewBackend () (output tomo.Backend, err error) {
backend := &Backend {
windows: map[xproto.Window] *Window { },
}
// 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
case callback := <- backend.doChannel:
callback()
case <- pingQuit: return
}
}
}
// Stop gracefully closes the connection and stops the event loop.
func (backend *Backend) Stop () {
backend.assert()
for _, window := range backend.windows {
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
}
func (backend *Backend) assert () {
if backend == nil { panic("nil backend") }
}
func init () {
tomo.RegisterBackend(NewBackend)
}