2020-08-18 11:15:45 +00:00
|
|
|
package display
|
|
|
|
|
2021-10-24 12:12:22 +00:00
|
|
|
// #cgo CFLAGS: --std=gnu99 -pedantic -Wall
|
|
|
|
// #cgo LDFLAGS: -lX11 -lXext
|
|
|
|
// #include "dpms.h"
|
|
|
|
// #include <stdlib.h>
|
|
|
|
// #include <stdbool.h>
|
|
|
|
import "C"
|
2020-08-18 11:15:45 +00:00
|
|
|
import (
|
2021-10-24 12:12:22 +00:00
|
|
|
"unsafe"
|
|
|
|
"errors"
|
|
|
|
"os"
|
2020-08-18 11:15:45 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2021-10-24 12:12:22 +00:00
|
|
|
// Xset monitors/controls the display using the DPMS X extension
|
2020-08-20 14:57:57 +00:00
|
|
|
type Xset struct {}
|
|
|
|
|
|
|
|
// Suspend the display
|
|
|
|
func (Xset) Suspend() error {
|
2021-10-24 12:12:22 +00:00
|
|
|
xDisplayName := C.CString(tryGetXDisplay())
|
|
|
|
defer C.free(unsafe.Pointer(xDisplayName))
|
|
|
|
|
|
|
|
err := C.turn_display_off(xDisplayName)
|
|
|
|
if err != C.int(0) {
|
|
|
|
return convertErrorIntToGoError(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2020-08-18 11:15:45 +00:00
|
|
|
}
|
|
|
|
|
2021-10-24 12:12:22 +00:00
|
|
|
func tryGetXDisplay() string {
|
|
|
|
display := os.Getenv("DISPLAY")
|
|
|
|
if display == "" {
|
|
|
|
panic(errors.New("DISPLAY envvar not set"))
|
2020-08-18 11:15:45 +00:00
|
|
|
}
|
2021-10-24 12:12:22 +00:00
|
|
|
return display
|
2020-08-18 11:15:45 +00:00
|
|
|
}
|
|
|
|
|
2021-10-24 12:12:22 +00:00
|
|
|
func convertErrorIntToGoError(err C.int) error {
|
|
|
|
errorMsg := ""
|
|
|
|
switch err {
|
|
|
|
case C.BADDISPLAY:
|
|
|
|
errorMsg = "Failed to open X display"
|
|
|
|
case C.NODPMSEXTENSION:
|
|
|
|
errorMsg = "DPMS extension is not available"
|
|
|
|
case C.NOTDPMSCAPABLE:
|
|
|
|
errorMsg = "Display is not DPMS capable"
|
|
|
|
case C.UNKNOWNDPMSMODE:
|
|
|
|
errorMsg = "Reported DPMS state unknown"
|
|
|
|
case C.DPMSDISABLED:
|
|
|
|
errorMsg = "DPMS is disabled"
|
|
|
|
default:
|
|
|
|
errorMsg = "Unknown error from dpms.h"
|
|
|
|
}
|
|
|
|
return errors.New(errorMsg)
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsOn determines if the display is on
|
|
|
|
func (Xset) IsOn() (bool, error) {
|
|
|
|
xDisplayName := C.CString(tryGetXDisplay())
|
|
|
|
defer C.free(unsafe.Pointer(xDisplayName))
|
|
|
|
var isDisplayOn C.bool
|
|
|
|
|
|
|
|
err := C.is_display_on(xDisplayName, &isDisplayOn)
|
|
|
|
if err != C.int(0) {
|
|
|
|
return false, convertErrorIntToGoError(err)
|
2020-08-18 11:15:45 +00:00
|
|
|
}
|
|
|
|
|
2021-10-24 12:12:22 +00:00
|
|
|
if isDisplayOn {
|
|
|
|
return true, nil
|
2020-08-18 11:15:45 +00:00
|
|
|
}
|
2021-10-24 12:12:22 +00:00
|
|
|
return false, nil
|
2020-08-18 11:15:45 +00:00
|
|
|
}
|