package qemuconnection import ( "encoding/json" "fmt" "github.com/digitalocean/go-qemu/qmp" ) const ( MouseMoveEvent = iota MouseButtonEvent KeyboardEvent ControlEvent QueryStatusEvent ) const ( ControlEventRestart = iota ) type Event struct { Type int `json:"type"` Args map[string]any `json:"args"` } type CommandLine struct { Command string `json:"command-line"` } func ParseEvent(b []byte) (*Event, error) { event := &Event{} if err := json.Unmarshal(b, event); err != nil { return nil, err } return event, nil } func (e *Event) ToQemuCommand() []qmp.Command { switch e.Type { case MouseMoveEvent: return []qmp.Command{ makeHMCommand("mouse_move %d %d %d", e.Args["dx"], e.Args["dy"], e.Args["dz"]), } case MouseButtonEvent: return []qmp.Command{ makeHMCommand("mouse_button %d", e.Args["button"]), } case KeyboardEvent: return []qmp.Command{ makeHMCommand("sendkey %s", e.Args["key"]), } case ControlEvent: t, ok := e.Args["cmd"].(int) if ok { return makeControlCommand(t) } case QueryStatusEvent: return []qmp.Command{ { Execute: "query-status", }, } } return make([]qmp.Command, 0) } func makeControlCommand(t int) []qmp.Command { switch t { case ControlEventRestart: return []qmp.Command{ makeHMCommand("system_reset"), makeHMCommand("cont"), } } return make([]qmp.Command, 0) } func makeHMCommand(cmdTemplate string, args ...any) qmp.Command { return qmp.Command{ Execute: "human-monitor-command", Args: CommandLine{ Command: fmt.Sprintf(cmdTemplate, args...), }, } }