kde-lockscreen-suspend-display/xdg/xinput_devnodes/xinput_devnodes.go

92 lines
2.0 KiB
Go

package xinput_devnodes
// #cgo CFLAGS: -g --std=gnu99 -pedantic -Wall
// #cgo LDFLAGS: -lX11 -lXi
// #include "devnodes.h"
// #include <stdlib.h>
// #include <string.h>
import "C"
import (
"fmt"
"unsafe"
"regexp"
"errors"
"os"
)
func FindKeyboardDevNode() string {
xslaveinfos, freeMethod := GetXSlaveInfo()
defer freeMethod()
re := regexp.MustCompile(`(?i).*keyboard.*`)
for _, xslaveinfo := range xslaveinfos {
name, devNode := C.GoString(xslaveinfo.name), C.GoString(xslaveinfo.dev_node)
if re.MatchString(name) {
return devNode
}
}
return ""
}
func Print() {
xslaveinfos, freeMethod := GetXSlaveInfo()
defer freeMethod()
for _, xslaveinfo := range xslaveinfos {
fmt.Printf("%s = %s\n", C.GoString(xslaveinfo.name), C.GoString(xslaveinfo.dev_node))
}
}
func GetXSlaveInfo() ([]C.XSlaveInfo, func()) {
xDisplayName := C.CString(tryGetXDisplay())
defer C.free(unsafe.Pointer(xDisplayName))
var error C.int
xslaves := C.get_slave_info(xDisplayName, &error)
if (error != C.int(0)) {
panic(convertErrorIntToGoError(error))
}
arr := (*[1 << 30]C.XSlaveInfo)(unsafe.Pointer(xslaves.slaves))
slice := arr[:xslaves.length:xslaves.length]
freeMethod := func() {
C.free_xslaves(xslaves)
}
return slice, freeMethod
}
func tryGetXDisplay() string {
display := os.Getenv("DISPLAY")
if display == "" {
panic(errors.New("DISPLAY envvar not set"))
}
return display
}
func convertErrorIntToGoError(err C.int) error {
errorMsg := ""
switch err {
case C.MALLOCFAIL:
errorMsg = "Memory allocation failed"
case C.XSLAVESFULL:
errorMsg = "XSlaves full"
case C.BADDISPLAY:
errorMsg = "Failed to open X display"
case C.XINPUTEXTUNAVAIL:
errorMsg = "XInput extension unavailable"
case C.XINPUT20UNAVAIL:
errorMsg = "XInput extension is not 2.0"
case C.XINPUTQUERYVERSIONFAILED:
errorMsg = "Failed to query XInput extension version"
case C.XSLAVEINFOQUERYFAILED:
errorMsg = "Failed to query XInput slaves"
default:
errorMsg = fmt.Sprintf("Unknown error from devnodes.h: %v", err)
}
return errors.New(errorMsg)
}