-
Notifications
You must be signed in to change notification settings - Fork 289
feat(display.go): Add display brightness settings #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
3271a17
4fd8b1e
cd7258e
bec1443
f4d88c7
db4c0c7
a267bb3
74cdeca
d6e4df2
7e7310b
1fe71da
e9b5390
daaddef
79bac39
34e42fd
e9f140c
7d17779
cabe5b0
309d30d
a6eab94
a05df7a
6445628
f5035f2
9896eba
8071f81
ce54d10
e177fdb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,22 @@ | ||
| package kvm | ||
|
|
||
| import ( | ||
| "errors" | ||
| "fmt" | ||
| "log" | ||
| "os" | ||
| "strconv" | ||
| "time" | ||
| ) | ||
|
|
||
| var currentScreen = "ui_Boot_Screen" | ||
| var lastWakeTime = time.Now() | ||
| var backlightState = 0 // 0 - NORMAL, 1 - DIMMED, 2 - OFF | ||
|
|
||
| const ( | ||
| TOUCHSCREEN_DEVICE string = "/dev/input/event1" | ||
| BACKLIGHT_CONTROL_CLASS string = "/sys/class/backlight/backlight/brightness" | ||
| ) | ||
|
|
||
| func switchToScreen(screen string) { | ||
| _, err := CallCtrlAction("lv_scr_load", map[string]interface{}{"obj": screen}) | ||
|
|
@@ -65,6 +75,7 @@ func requestDisplayUpdate() { | |
| return | ||
| } | ||
| go func() { | ||
| wakeDisplay() | ||
| fmt.Println("display updating........................") | ||
| //TODO: only run once regardless how many pending updates | ||
| updateDisplay() | ||
|
|
@@ -83,6 +94,109 @@ func updateStaticContents() { | |
| updateLabelIfChanged("ui_Status_Content_Device_Id_Content_Label", GetDeviceID()) | ||
| } | ||
|
|
||
| // setDisplayBrightness sets /sys/class/backlight/backlight/brightness to alter | ||
| // the backlight brightness of the JetKVM hardware's display. | ||
| func setDisplayBrightness(brightness int) error { | ||
| if brightness > 100 || brightness < 0 { | ||
Nevexo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return errors.New("brightness value out of bounds, must be between 0 and 100") | ||
| } | ||
|
|
||
| // Check the display backlight class is available | ||
| if _, err := os.Stat(BACKLIGHT_CONTROL_CLASS); errors.Is(err, os.ErrNotExist) { | ||
| return errors.New("brightness value cannot be set, possibly not running on JetKVM hardware.") | ||
| } | ||
|
|
||
| // Set the value | ||
| bs := []byte(strconv.Itoa(brightness)) | ||
| err := os.WriteFile(BACKLIGHT_CONTROL_CLASS, bs, 0644) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| fmt.Printf("display: set brightness to %v", brightness) | ||
Nevexo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return nil | ||
| } | ||
|
|
||
| // displayTimeoutTick checks the time the display was last woken, and compares that to the | ||
| // config's displayTimeout values to decide whether or not to dim/switch off the display. | ||
| func displayTimeoutTick() { | ||
| tn := time.Now() | ||
| td := tn.Sub(lastWakeTime).Milliseconds() | ||
|
|
||
| // fmt.Printf("display: tick: time since wake: %vms, dim after: %v, off after: %v\n", td, config.DisplayDimAfterMs, config.DisplayOffAfterMs) | ||
Nevexo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| if td > config.DisplayOffAfterMs && config.DisplayOffAfterMs != 0 && (backlightState == 1 || backlightState == 0) { | ||
| // Display fully off | ||
|
|
||
| backlightState = 2 | ||
| err := setDisplayBrightness(0) | ||
| if err != nil { | ||
| fmt.Printf("display: timeout: Failed to switch off backlight: %s\n", err) | ||
| } | ||
|
|
||
| } else if td > config.DisplayDimAfterMs && config.DisplayDimAfterMs != 0 && backlightState == 0 { | ||
| // Display dimming | ||
|
|
||
| // Get 50% of max brightness, rounded up. | ||
| dimBright := config.DisplayMaxBrightness / 2 | ||
| fmt.Printf("display: timeout: target dim brightness: %v\n", dimBright) | ||
|
|
||
| backlightState = 1 | ||
| err := setDisplayBrightness(dimBright) | ||
| if err != nil { | ||
| fmt.Printf("display: timeout: Failed to dim backlight: %s\n", err) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // wakeDisplay sets the display brightness back to config.DisplayMaxBrightness and stores the time the display | ||
| // last woke, ready for displayTimeoutTick to put the display back in the dim/off states. | ||
| func wakeDisplay() { | ||
| if backlightState == 0 { | ||
| return | ||
| } | ||
|
|
||
| if config.DisplayMaxBrightness == 0 { | ||
| config.DisplayMaxBrightness = 100 | ||
| } | ||
|
|
||
| err := setDisplayBrightness(config.DisplayMaxBrightness) | ||
| if err != nil { | ||
| fmt.Printf("display wake failed, %s\n", err) | ||
| } | ||
|
|
||
| lastWakeTime = time.Now() | ||
| backlightState = 0 | ||
| } | ||
|
|
||
| // watchTsEvents monitors the touchscreen for events and simply calls wakeDisplay() to ensure the | ||
| // touchscreen interface still works even with LCD dimming/off. | ||
| // TODO: This is quite a hack, really we should be getting an event from jetkvm_native, or the whole display backlight | ||
| // control should be hoisted up to jetkvm_native. | ||
| func watchTsEvents() { | ||
| // Open touchscreen device | ||
| ts, err := os.OpenFile(TOUCHSCREEN_DEVICE, os.O_RDONLY, 0666) | ||
| if err != nil { | ||
| fmt.Printf("display: failed to open touchscreen device: %s\n", err) | ||
| return | ||
| } | ||
|
|
||
| defer ts.Close() | ||
|
|
||
| // Watch for events | ||
| buf := make([]byte, 24) | ||
| for { | ||
| _, err := ts.Read(buf) | ||
| if err != nil { | ||
| fmt.Printf("display: failed to read from touchscreen device: %s\n", err) | ||
| return | ||
| } | ||
|
|
||
| // Touchscreen event, wake the display | ||
| wakeDisplay() | ||
| } | ||
| } | ||
|
|
||
| func init() { | ||
| go func() { | ||
| waitCtrlClientConnected() | ||
|
|
@@ -91,6 +205,22 @@ func init() { | |
| updateStaticContents() | ||
| displayInited = true | ||
| fmt.Println("display inited") | ||
| wakeDisplay() | ||
| requestDisplayUpdate() | ||
| }() | ||
|
|
||
| go func() { | ||
| // Start display auto-sleeping ticker | ||
| ticker := time.NewTicker(1 * time.Second) | ||
|
||
| defer ticker.Stop() | ||
|
|
||
| for { | ||
| select { | ||
| case <-ticker.C: | ||
| displayTimeoutTick() | ||
| } | ||
| } | ||
| }() | ||
|
|
||
| go watchTsEvents() | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Effective Go and the Go stdlib usually prefers lowerCamelCase/UpperCamelCase (depending on whether exported) for constant names. E.g., per https://go.dev/wiki/CodeReviewComments:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Updated.