stone/backends/x/event.go

120 lines
2.9 KiB
Go

package x
import "image"
import "github.com/jezek/xgbutil"
import "github.com/jezek/xgb/xproto"
import "github.com/jezek/xgbutil/xevent"
import "git.tebibyte.media/sashakoshka/stone"
func (backend *Backend) Run (channel chan(stone.Event)) {
backend.channel = channel
xevent.Main(backend.connection)
backend.shutDown()
}
func (backend *Backend) handleConfigureNotify (
connection *xgbutil.XUtil,
event xevent.ConfigureNotifyEvent,
) {
configureEvent := *event.ConfigureNotifyEvent
newWidth := int(configureEvent.Width)
newHeight := int(configureEvent.Height)
sizeChanged :=
backend.metrics.windowWidth != newWidth ||
backend.metrics.windowHeight != newHeight
backend.metrics.windowWidth = newWidth
backend.metrics.windowHeight = newHeight
if sizeChanged {
configureEvent =
backend.compressConfigureNotify(configureEvent)
backend.application.SetSize(backend.calculateBufferSize())
backend.channel <- stone.EventResize { }
}
}
func (backend *Backend) handleButtonPress (
connection *xgbutil.XUtil,
event xevent.ButtonPressEvent,
) {
buttonEvent := *event.ButtonPressEvent
backend.channel <- stone.EventPress {
Button: stone.Button(buttonEvent.Detail),
}
}
func (backend *Backend) handleButtonRelease (
connection *xgbutil.XUtil,
event xevent.ButtonReleaseEvent,
) {
buttonEvent := *event.ButtonReleaseEvent
backend.channel <- stone.EventRelease {
Button: stone.Button(buttonEvent.Detail),
}
}
func (backend *Backend) handleKeyPress (
connection *xgbutil.XUtil,
event xevent.KeyPressEvent,
) {
keyEvent := *event.KeyPressEvent
button := backend.keycodeToButton(keyEvent.Detail, keyEvent.State)
backend.channel <- stone.EventPress { Button: button }
}
func (backend *Backend) handleKeyRelease (
connection *xgbutil.XUtil,
event xevent.KeyReleaseEvent,
) {
keyEvent := *event.KeyReleaseEvent
button := backend.keycodeToButton(keyEvent.Detail, keyEvent.State)
backend.channel <- stone.EventRelease { Button: button }
}
func (backend *Backend) handleMotionNotify (
connection *xgbutil.XUtil,
event xevent.MotionNotifyEvent,
) {
motionEvent := *event.MotionNotifyEvent
x, y := backend.cellAt (image.Point {
X: int(motionEvent.EventX),
Y: int(motionEvent.EventY),
})
backend.channel <- stone.EventMouseMove {
X: x,
Y: y,
}
}
func (backend *Backend) compressConfigureNotify (
firstEvent xproto.ConfigureNotifyEvent,
) (
lastEvent xproto.ConfigureNotifyEvent,
) {
backend.connection.Sync()
xevent.Read(backend.connection, false)
lastEvent = firstEvent
for index, untypedEvent := range xevent.Peek(backend.connection) {
if untypedEvent.Err != nil { continue }
typedEvent, ok := untypedEvent.Event.(xproto.ConfigureNotifyEvent)
if !ok { continue }
lastEvent = typedEvent
defer func (index int) {
xevent.DequeueAt(backend.connection, index)
} (index)
}
return
}
func (backend *Backend) shutDown () {
backend.channel <- stone.EventQuit { }
}