stone/backends/x/event.go

215 lines
5.3 KiB
Go
Raw Normal View History

2022-11-13 20:44:19 -07:00
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"
type scrollSum struct {
x, y int
}
func (sum *scrollSum) add (button xproto.Button) {
switch button {
case 4:
sum.y --
case 5:
sum.y ++
case 6:
sum.x --
case 7:
sum.x ++
}
}
2022-11-15 22:29:23 -07:00
func (backend *Backend) Run () {
backend.callbackManager.RunStart()
backend.Draw()
2022-11-13 20:44:19 -07:00
xevent.Main(backend.connection)
2022-11-16 09:08:30 -07:00
backend.callbackManager.RunQuit()
2022-11-13 20:44:19 -07:00
}
func (backend *Backend) handleConfigureNotify (
connection *xgbutil.XUtil,
event xevent.ConfigureNotifyEvent,
) {
2022-11-15 22:29:23 -07:00
backend.lock.Lock()
2022-11-13 20:44:19 -07:00
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)
2022-11-14 21:38:41 -07:00
// resize buffer
width, height := backend.calculateBufferSize()
backend.application.SetSize(width, height)
if backend.config.Center() {
// position buffer in the center of the screen
frameWidth := width * backend.metrics.cellWidth
frameHeight := height * backend.metrics.cellHeight
backend.metrics.paddingX =
(backend.metrics.windowWidth - frameWidth) / 2
backend.metrics.paddingY =
(backend.metrics.windowHeight - frameHeight) / 2
} else {
backend.metrics.paddingX = backend.metrics.padding
backend.metrics.paddingY = backend.metrics.padding
}
backend.windowBoundsClean = false
2022-11-15 22:29:23 -07:00
}
backend.lock.Unlock()
if sizeChanged {
backend.callbackManager.RunResize()
backend.Draw()
2022-11-13 20:44:19 -07:00
}
}
func (backend *Backend) handleButtonPress (
connection *xgbutil.XUtil,
event xevent.ButtonPressEvent,
) {
buttonEvent := *event.ButtonPressEvent
2022-11-17 17:11:49 -07:00
if buttonEvent.Detail >= 4 && buttonEvent.Detail <= 7 {
sum := scrollSum { }
sum.add(buttonEvent.Detail)
backend.compressScrollSum(&sum)
backend.callbackManager.RunScroll(sum.x, sum.y)
2022-11-17 17:11:49 -07:00
} else {
backend.callbackManager.RunPress (
stone.Button(buttonEvent.Detail + 127),
stone.Modifiers { })
2022-11-17 17:11:49 -07:00
}
2022-11-13 20:44:19 -07:00
}
func (backend *Backend) handleButtonRelease (
connection *xgbutil.XUtil,
event xevent.ButtonReleaseEvent,
) {
buttonEvent := *event.ButtonReleaseEvent
2022-11-17 17:11:49 -07:00
if buttonEvent.Detail >= 4 && buttonEvent.Detail <= 7 { return }
2022-11-15 22:29:23 -07:00
backend.callbackManager.RunRelease(stone.Button(buttonEvent.Detail + 127))
2022-11-13 20:44:19 -07:00
}
func (backend *Backend) handleKeyPress (
connection *xgbutil.XUtil,
event xevent.KeyPressEvent,
) {
keyEvent := *event.KeyPressEvent
button, num := backend.keycodeToButton(keyEvent.Detail, keyEvent.State)
backend.callbackManager.RunPress (button, stone.Modifiers {
// FIXME these may not be correct in all cases
Shift: (keyEvent.State & xproto.ModMaskShift) > 0,
Control: (keyEvent.State & xproto.ModMaskControl) > 0,
Alt: (keyEvent.State & xproto.ModMask1) > 0,
// Meta: (keyEvent.State & xproto.??) > 0,
Super: (keyEvent.State & xproto.ModMask4) > 0,
// Hyper: (keyEvent.State & xproto.??) > 0,
NumberPad: num,
})
2022-11-13 21:47:35 -07:00
}
func (backend *Backend) handleKeyRelease (
connection *xgbutil.XUtil,
event xevent.KeyReleaseEvent,
2022-11-13 21:47:35 -07:00
) {
keyEvent := *event.KeyReleaseEvent
button, _ := backend.keycodeToButton(keyEvent.Detail, keyEvent.State)
2022-11-15 22:29:23 -07:00
backend.callbackManager.RunRelease(button)
2022-11-13 20:44:19 -07:00
}
func (backend *Backend) handleMotionNotify (
connection *xgbutil.XUtil,
event xevent.MotionNotifyEvent,
) {
2022-11-17 17:01:16 -07:00
motionEvent := backend.compressMotionNotify(*event.MotionNotifyEvent)
2022-11-13 20:44:19 -07:00
x, y := backend.cellAt (image.Point {
X: int(motionEvent.EventX),
Y: int(motionEvent.EventY),
})
2022-11-15 22:29:23 -07:00
backend.callbackManager.RunMouseMove(x, y)
2022-11-13 20:44:19 -07:00
}
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
}
2022-11-17 17:01:16 -07:00
func (backend *Backend) compressMotionNotify (
firstEvent xproto.MotionNotifyEvent,
) (
lastEvent xproto.MotionNotifyEvent,
) {
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.MotionNotifyEvent)
if !ok { continue }
lastEvent = typedEvent
defer func (index int) {
xevent.DequeueAt(backend.connection, index)
} (index)
}
return
}
func (backend *Backend) compressScrollSum (sum *scrollSum) {
backend.connection.Sync()
xevent.Read(backend.connection, false)
for index, untypedEvent := range xevent.Peek(backend.connection) {
if untypedEvent.Err != nil { continue }
typedEvent, ok := untypedEvent.Event.(xproto.ButtonPressEvent)
if !ok { continue }
sum.add(typedEvent.Detail)
defer func (index int) {
xevent.DequeueAt(backend.connection, index)
} (index)
}
return
}