From 6ed53fc45d138a16b92ef8367ff06b6b29796a1d Mon Sep 17 00:00:00 2001 From: The-Jonsey Date: Mon, 24 Aug 2020 17:58:37 +0100 Subject: [PATCH 01/10] WIP: Hotplug support --- dbus.go | 26 +++++++++---------- interface.go | 25 +++++++++++++------ main.go | 70 +++++++++++++++++++++++++++++++++++----------------- 3 files changed, 77 insertions(+), 44 deletions(-) diff --git a/dbus.go b/dbus.go index 4efccf6..d58fe58 100644 --- a/dbus.go +++ b/dbus.go @@ -7,16 +7,15 @@ import ( "log" ) - var conn *dbus.Conn -var s *StreamDeckDBus +var sDbus *StreamDeckDBus type StreamDeckDBus struct { - Cols int `json:"cols,omitempty"` - Rows int `json:"rows,omitempty"` + Cols int `json:"cols,omitempty"` + Rows int `json:"rows,omitempty"` IconSize int `json:"icon_size,omitempty"` - Page int `json:"page"` + Page int `json:"page"` } func (s StreamDeckDBus) GetDeckInfo() (string, *dbus.Error) { @@ -43,7 +42,7 @@ func (StreamDeckDBus) ReloadConfig() *dbus.Error { return nil } -func (StreamDeckDBus) SetPage(page int) *dbus.Error { +func (StreamDeckDBus) SetPage(page int) *dbus.Error { SetPage(config, page, dev) return nil } @@ -73,13 +72,10 @@ func InitDBUS() error { } defer conn.Close() - s = &StreamDeckDBus{ - Cols: int(dev.Columns), - Rows: int(dev.Rows), - IconSize: int(dev.Pixels), + sDbus = &StreamDeckDBus{ Page: p, } - conn.ExportAll(s, "/com/unixstreamdeck/streamdeckd", "com.unixstreamdeck.streamdeckd") + conn.ExportAll(sDbus, "/com/unixstreamdeck/streamdeckd", "com.unixstreamdeck.streamdeckd") reply, err := conn.RequestName("com.unixstreamdeck.streamdeckd", dbus.NameFlagDoNotQueue) if err != nil { @@ -89,14 +85,14 @@ func InitDBUS() error { if reply != dbus.RequestNameReplyPrimaryOwner { return errors.New("DBus: Name already taken") } - select {} + select {} } func EmitPage(page int) { if conn != nil { conn.Emit("/com/unixstreamdeck/streamdeckd", "com.unixstreamdeck.streamdeckd.Page", page) } - if s != nil { - s.Page = page + if sDbus != nil { + sDbus.Page = page } -} \ No newline at end of file +} diff --git a/interface.go b/interface.go index aae6f5f..6f618a3 100644 --- a/interface.go +++ b/interface.go @@ -11,6 +11,7 @@ import ( "image/draw" "log" "os" + "strings" ) var p int @@ -35,8 +36,18 @@ func ResizeImage(img image.Image) image.Image { } func SetImage(img image.Image, i int, page int, dev streamdeck.Device) { - if p == page { - dev.SetImage(uint8(i), img) + if p == page && isOpen { + err := dev.SetImage(uint8(i), img) + if err != nil { + if strings.Contains(err.Error(), "hidapi") { + log.Println("Device disconnected") + _ = dev.Close() + isOpen = false + unmountHandlers() + } else { + log.Println(err) + } + } } } @@ -136,14 +147,14 @@ func Listen() { if err != nil { log.Println(err) } - for { + for isOpen { select { case k, ok := <-kch: if !ok { - err = dev.Open() - if err != nil { - log.Println(err) - } + log.Println("Device disconnected") + _ = dev.Close() + isOpen = false + unmountHandlers() continue } if k.Pressed == true { diff --git a/main.go b/main.go index 6e8a72d..4c1f831 100644 --- a/main.go +++ b/main.go @@ -2,8 +2,10 @@ package main import ( "encoding/json" - "github.com/unix-streamdeck/driver" + "errors" + "fmt" "github.com/unix-streamdeck/api" + "github.com/unix-streamdeck/driver" _ "image/gif" _ "image/jpeg" _ "image/png" @@ -17,30 +19,19 @@ import ( var dev streamdeck.Device var config *api.Config -var configPath = os.Getenv("HOME") + "/.streamdeck-config.json" +var configPath = os.Getenv("HOME") + string(os.PathSeparator) + ".streamdeck-config.json" +var isOpen = false var basicConfig = api.Config{ Pages: []api.Page{ { - api.Key{ - }, + api.Key{}, }, }, } func main() { - d, err := streamdeck.Devices() - if err != nil { - log.Println(err) - } - if len(d) == 0 { - log.Println("No Stream Deck devices found.") - } - dev = d[0] - err = dev.Open() - if err != nil { - log.Println(err) - } + var err error config, err = readConfig() if err != nil && !os.IsNotExist(err) { log.Println(err) @@ -63,9 +54,43 @@ func main() { config.Pages = append(config.Pages, api.Page{}) } cleanupHook() - SetPage(config, 0, dev) go InitDBUS() - Listen() + attemptConnection() +} + +func attemptConnection() { + for { + if !isOpen { + _ = openDevice() + if isOpen { + go Listen() + SetPage(config, p, dev) + if sDbus != nil { + sDbus.IconSize = int(dev.Pixels) + sDbus.Rows = int(dev.Rows) + sDbus.Cols = int(dev.Columns) + } + } + } + } +} + +func openDevice() error { + d, err := streamdeck.Devices() + if err != nil { + return err + } + if len(d) == 0 { + return errors.New("No streamdeck devices found") + } + dev = d[0] + err = dev.Open() + if err != nil { + return err + } + isOpen = true + fmt.Println("Device (" + dev.Serial + ") connected") + return err } func readConfig() (*api.Config, error) { @@ -81,7 +106,6 @@ func readConfig() (*api.Config, error) { return &config, nil } - func runCommand(command string) { //args := strings.Split(command, " ") c := exec.Command("/bin/sh", "-c", command) @@ -158,11 +182,13 @@ func SaveConfig() error { func unmountHandlers() { for i := range config.Pages { page := config.Pages[i] - for i2 := range page { - key := page[i2] + for i2 := 0; i2 < len(page); i2++ { + key := &page[i2] if key.IconHandlerStruct != nil { key.IconHandlerStruct.Stop() + key.IconHandlerStruct = nil + key.Buff = nil } } } -} \ No newline at end of file +} From f7d731fbee6a794e8347897e89f2c72c58bf1500 Mon Sep 17 00:00:00 2001 From: The-Jonsey Date: Tue, 25 Aug 2020 16:14:28 +0100 Subject: [PATCH 02/10] Refactored resizing of frames to happen before loop --- GifHandler.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/GifHandler.go b/GifHandler.go index 820241c..eced553 100644 --- a/GifHandler.go +++ b/GifHandler.go @@ -3,6 +3,7 @@ package main import ( "github.com/unix-streamdeck/api" "github.com/unix-streamdeck/driver" + "image" "image/gif" "log" "os" @@ -21,24 +22,32 @@ func (s *GifIconHandler) Icon(page int, index int, key *api.Key, dev streamdeck. return } gifs, err := gif.DecodeAll(f) + if err != nil { + log.Println(err) + return + } timeDelay := gifs.Delay[0] - gifIndex := 0 - go loop(gifs, gifIndex, timeDelay, page, index, dev, key, s) + frames := make([]image.Image, len(gifs.Image)) + for i, frame := range gifs.Image { + frames[i] = ResizeImage(frame) + } + go loop(frames, timeDelay, page, index, dev, key, s) } func (s *GifIconHandler) Stop() { s.running = false } -func loop(gifs *gif.GIF, gifIndex int, timeDelay int, page int, index int, dev streamdeck.Device, key *api.Key, s *GifIconHandler) { +func loop(frames []image.Image, timeDelay int, page int, index int, dev streamdeck.Device, key *api.Key, s *GifIconHandler) { + gifIndex := 0 for s.running { - img := ResizeImage(gifs.Image[gifIndex]) + img := frames[gifIndex] SetImage(img, index, page, dev) key.Buff = img gifIndex++ - if gifIndex >= len(gifs.Image) { + if gifIndex >= len(frames) { gifIndex = 0 } time.Sleep(time.Duration(timeDelay * 10000000)) } -} \ No newline at end of file +} From e3ceae0dcaa8fd311b7b67c44865f7048c390440 Mon Sep 17 00:00:00 2001 From: The-Jonsey Date: Tue, 25 Aug 2020 16:15:35 +0100 Subject: [PATCH 03/10] Added semaphore lock around SetImage to prevent handlers running on other threads interfering with each other --- go.mod | 1 + go.sum | 1 + interface.go | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/go.mod b/go.mod index 0d6bdc3..20ebc75 100644 --- a/go.mod +++ b/go.mod @@ -10,4 +10,5 @@ require ( github.com/unix-streamdeck/api v0.0.0-20200818180846-6942d99617b2 github.com/unix-streamdeck/driver v0.0.0-20200817173808-cdaf123c076b golang.org/x/image v0.0.0-20200119044424-58c23975cae1 + golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 ) diff --git a/go.sum b/go.sum index c887392..cf3def9 100644 --- a/go.sum +++ b/go.sum @@ -115,6 +115,7 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/interface.go b/interface.go index aae6f5f..7f4873f 100644 --- a/interface.go +++ b/interface.go @@ -1,11 +1,13 @@ package main import ( + "context" "github.com/fogleman/gg" "github.com/nfnt/resize" "github.com/unix-streamdeck/api" "github.com/unix-streamdeck/driver" "golang.org/x/image/font/inconsolata" + "golang.org/x/sync/semaphore" "image" "image/color" "image/draw" @@ -14,6 +16,7 @@ import ( ) var p int +var sem = semaphore.NewWeighted(int64(1)) func LoadImage(path string) (image.Image, error) { f, err := os.Open(path) @@ -35,6 +38,13 @@ func ResizeImage(img image.Image) image.Image { } func SetImage(img image.Image, i int, page int, dev streamdeck.Device) { + ctx := context.Background() + err := sem.Acquire(ctx, 1) + if err != nil { + log.Println(err) + return + } + defer sem.Release(1) if p == page { dev.SetImage(uint8(i), img) } From 40f83f8e6dcfcba58fd9ee5e3a662d10d4d365a9 Mon Sep 17 00:00:00 2001 From: The-Jonsey Date: Tue, 25 Aug 2020 16:16:42 +0100 Subject: [PATCH 04/10] Refactored SetPage so all keys on page are rendered on seperate threads, to reduce page change latency --- interface.go | 51 +++++++++++++++++++++++++++++---------------------- main.go | 2 +- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/interface.go b/interface.go index 7f4873f..937adcb 100644 --- a/interface.go +++ b/interface.go @@ -50,7 +50,7 @@ func SetImage(img image.Image, i int, page int, dev streamdeck.Device) { } } -func SetKey(currentKey *api.Key, i int) { +func SetKeyImage(currentKey *api.Key, i int) { if currentKey.Buff == nil { if currentKey.Icon == "" { img := image.NewRGBA(image.Rect(0, 0, int(dev.Pixels), int(dev.Pixels))) @@ -83,30 +83,34 @@ func SetPage(config *api.Config, page int, dev streamdeck.Device) { currentPage := config.Pages[page] for i := 0; i < len(currentPage); i++ { currentKey := ¤tPage[i] - if currentKey.Buff == nil { - if currentKey.IconHandler == "" { - SetKey(currentKey, i) + go SetKey(currentKey, i, page, dev) + } + EmitPage(p) +} - } else if currentKey.IconHandlerStruct == nil { - var handler api.IconHandler - if currentKey.IconHandler == "Gif" { - handler = &GifIconHandler{true} - } else if currentKey.IconHandler == "Counter" { - handler = &CounterIconHandler{0, true} - } else if currentKey.IconHandler == "Time" { - handler = &TimeIconHandler{true} - } - if handler == nil { - continue - } - handler.Icon(page, i, currentKey, dev) - currentKey.IconHandlerStruct = handler +func SetKey(currentKey *api.Key, i int, page int, dev streamdeck.Device) { + if currentKey.Buff == nil { + if currentKey.IconHandler == "" { + SetKeyImage(currentKey, i) + + } else if currentKey.IconHandlerStruct == nil { + var handler api.IconHandler + if currentKey.IconHandler == "Gif" { + handler = &GifIconHandler{true} + } else if currentKey.IconHandler == "Counter" { + handler = &CounterIconHandler{0, true} + } else if currentKey.IconHandler == "Time" { + handler = &TimeIconHandler{true} } - } else { - SetImage(currentKey.Buff, i, p, dev) + if handler == nil { + return + } + handler.Icon(page, i, currentKey, dev) + currentKey.IconHandlerStruct = handler } + } else { + SetImage(currentKey.Buff, i, p, dev) } - EmitPage(p) } func HandleInput(key *api.Key, page int, index int, dev streamdeck.Device) { @@ -121,7 +125,10 @@ func HandleInput(key *api.Key, page int, index int, dev streamdeck.Device) { SetPage(config, page, dev) } if key.Brightness != 0 { - _ = dev.SetBrightness(uint8(key.Brightness)) + err := dev.SetBrightness(uint8(key.Brightness)) + if err != nil { + log.Println(err) + } } if key.Url != "" { runCommand("xdg-open " + key.Url) diff --git a/main.go b/main.go index 6e8a72d..642cb1b 100644 --- a/main.go +++ b/main.go @@ -2,8 +2,8 @@ package main import ( "encoding/json" - "github.com/unix-streamdeck/driver" "github.com/unix-streamdeck/api" + "github.com/unix-streamdeck/driver" _ "image/gif" _ "image/jpeg" _ "image/png" From 57294fe121e920976c8c7b4326752c36da4a135c Mon Sep 17 00:00:00 2001 From: The-Jonsey Date: Wed, 26 Aug 2020 16:34:17 +0100 Subject: [PATCH 05/10] added semaphores around disconnect and reconnect to prevent crash due to double (dis)connect --- dbus.go | 2 +- go.mod | 1 + go.sum | 1 + interface.go | 26 ++++++++++-------------- main.go | 56 +++++++++++++++++++++++++++++++++++++--------------- 5 files changed, 53 insertions(+), 33 deletions(-) diff --git a/dbus.go b/dbus.go index d58fe58..30c823a 100644 --- a/dbus.go +++ b/dbus.go @@ -43,7 +43,7 @@ func (StreamDeckDBus) ReloadConfig() *dbus.Error { } func (StreamDeckDBus) SetPage(page int) *dbus.Error { - SetPage(config, page, dev) + SetPage(config, page) return nil } diff --git a/go.mod b/go.mod index 0d6bdc3..20ebc75 100644 --- a/go.mod +++ b/go.mod @@ -10,4 +10,5 @@ require ( github.com/unix-streamdeck/api v0.0.0-20200818180846-6942d99617b2 github.com/unix-streamdeck/driver v0.0.0-20200817173808-cdaf123c076b golang.org/x/image v0.0.0-20200119044424-58c23975cae1 + golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 ) diff --git a/go.sum b/go.sum index c887392..cf3def9 100644 --- a/go.sum +++ b/go.sum @@ -115,6 +115,7 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/interface.go b/interface.go index 6f618a3..a9a34e4 100644 --- a/interface.go +++ b/interface.go @@ -35,15 +35,12 @@ func ResizeImage(img image.Image) image.Image { return resize.Resize(dev.Pixels, dev.Pixels, img, resize.Lanczos3) } -func SetImage(img image.Image, i int, page int, dev streamdeck.Device) { +func SetImage(img image.Image, i int, page int, _ streamdeck.Device) { if p == page && isOpen { err := dev.SetImage(uint8(i), img) if err != nil { if strings.Contains(err.Error(), "hidapi") { - log.Println("Device disconnected") - _ = dev.Close() - isOpen = false - unmountHandlers() + disconnect() } else { log.Println(err) } @@ -79,7 +76,7 @@ func SetKey(currentKey *api.Key, i int) { } } -func SetPage(config *api.Config, page int, dev streamdeck.Device) { +func SetPage(config *api.Config, page int) { p = page currentPage := config.Pages[page] for i := 0; i < len(currentPage); i++ { @@ -100,7 +97,7 @@ func SetPage(config *api.Config, page int, dev streamdeck.Device) { if handler == nil { continue } - handler.Icon(page, i, currentKey, dev) + handler.Icon(page, i, currentKey, streamdeck.Device{}) currentKey.IconHandlerStruct = handler } } else { @@ -110,7 +107,7 @@ func SetPage(config *api.Config, page int, dev streamdeck.Device) { EmitPage(p) } -func HandleInput(key *api.Key, page int, index int, dev streamdeck.Device) { +func HandleInput(key *api.Key, page int, index int) { if key.Command != "" { runCommand(key.Command) } @@ -119,7 +116,7 @@ func HandleInput(key *api.Key, page int, index int, dev streamdeck.Device) { } if key.SwitchPage != 0 { page = key.SwitchPage - 1 - SetPage(config, page, dev) + SetPage(config, page) } if key.Brightness != 0 { _ = dev.SetBrightness(uint8(key.Brightness)) @@ -138,7 +135,7 @@ func HandleInput(key *api.Key, page int, index int, dev streamdeck.Device) { } key.KeyHandlerStruct = handler } - key.KeyHandlerStruct.Key(page, index, key, dev) + key.KeyHandlerStruct.Key(page, index, key, streamdeck.Device{}) } } @@ -151,15 +148,12 @@ func Listen() { select { case k, ok := <-kch: if !ok { - log.Println("Device disconnected") - _ = dev.Close() - isOpen = false - unmountHandlers() - continue + disconnect() + return } if k.Pressed == true { if len(config.Pages)-1 >= p && len(config.Pages[p])-1 >= int(k.Index) { - HandleInput(&config.Pages[p][k.Index], p, int(k.Index), dev) + HandleInput(&config.Pages[p][k.Index], p, int(k.Index)) } } } diff --git a/main.go b/main.go index 4c1f831..9956d7c 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,13 @@ package main import ( + "context" "encoding/json" "errors" "fmt" "github.com/unix-streamdeck/api" "github.com/unix-streamdeck/driver" + "golang.org/x/sync/semaphore" _ "image/gif" _ "image/jpeg" _ "image/png" @@ -21,6 +23,8 @@ var dev streamdeck.Device var config *api.Config var configPath = os.Getenv("HOME") + string(os.PathSeparator) + ".streamdeck-config.json" var isOpen = false +var disconnectSem = semaphore.NewWeighted(1) +var connectSem = semaphore.NewWeighted(1) var basicConfig = api.Config{ Pages: []api.Page{ @@ -59,23 +63,43 @@ func main() { } func attemptConnection() { - for { - if !isOpen { - _ = openDevice() - if isOpen { - go Listen() - SetPage(config, p, dev) - if sDbus != nil { - sDbus.IconSize = int(dev.Pixels) - sDbus.Rows = int(dev.Rows) - sDbus.Cols = int(dev.Columns) - } + for !isOpen { + _ = openDevice() + if isOpen { + SetPage(config, p) + if sDbus != nil { + sDbus.IconSize = int(dev.Pixels) + sDbus.Rows = int(dev.Rows) + sDbus.Cols = int(dev.Columns) } + Listen() } } } +func disconnect() { + ctx := context.Background() + err := disconnectSem.Acquire(ctx, 1) + if err != nil { + return + } + defer disconnectSem.Release(1) + if !isOpen { + return + } + log.Println("Device disconnected") + _ = dev.Close() + isOpen = false + unmountHandlers() +} + func openDevice() error { + ctx := context.Background() + err := connectSem.Acquire(ctx, 1) + if err != nil { + return err + } + defer connectSem.Release(1) d, err := streamdeck.Devices() if err != nil { return err @@ -83,14 +107,14 @@ func openDevice() error { if len(d) == 0 { return errors.New("No streamdeck devices found") } - dev = d[0] - err = dev.Open() + err = d[0].Open() if err != nil { return err } + dev = d[0] isOpen = true fmt.Println("Device (" + dev.Serial + ") connected") - return err + return nil } func readConfig() (*api.Config, error) { @@ -139,7 +163,7 @@ func SetConfig(configString string) error { if len(config.Pages) == 0 { config.Pages = append(config.Pages, api.Page{}) } - SetPage(config, p, dev) + SetPage(config, p) return nil } @@ -153,7 +177,7 @@ func ReloadConfig() error { if len(config.Pages) == 0 { config.Pages = append(config.Pages, api.Page{}) } - SetPage(config, p, dev) + SetPage(config, p) return nil } From e5df054e6eb6d9a98c7d88027c6c11424d4ba7aa Mon Sep 17 00:00:00 2001 From: The-Jonsey Date: Thu, 27 Aug 2020 15:46:20 +0100 Subject: [PATCH 06/10] Sorted imports --- interface.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface.go b/interface.go index b2d3c9b..645a3e1 100644 --- a/interface.go +++ b/interface.go @@ -5,8 +5,8 @@ import ( "github.com/nfnt/resize" "github.com/unix-streamdeck/api" "github.com/unix-streamdeck/driver" - "golang.org/x/image/font/inconsolata" "github.com/unix-streamdeck/streamdeckd/handlers" + "golang.org/x/image/font/inconsolata" "image" "image/color" "image/draw" @@ -98,7 +98,7 @@ func SetPage(config *api.Config, page int) { if handler == nil { continue } - handler.Icon(page, i, currentKey, streamdeck.Device{}) + handler.Icon(page, i, currentKey, dev) currentKey.IconHandlerStruct = handler } } else { From 250a249b09e09bbc77f7a6bd9996ed4420980185 Mon Sep 17 00:00:00 2001 From: The-Jonsey Date: Thu, 27 Aug 2020 16:15:18 +0100 Subject: [PATCH 07/10] Refactored handlers --- dbus.go | 11 +++++------ handlers/counter.go | 17 ++++++++++++----- handlers/gif.go | 11 +++++------ handlers/handlers.go | 9 ++------- handlers/time.go | 23 +++++++---------------- interface.go | 27 ++++++++++++++------------- main.go | 6 +++--- 7 files changed, 48 insertions(+), 56 deletions(-) diff --git a/dbus.go b/dbus.go index 30c823a..4c7da8e 100644 --- a/dbus.go +++ b/dbus.go @@ -4,18 +4,16 @@ import ( "encoding/json" "errors" "github.com/godbus/dbus/v5" + "github.com/unix-streamdeck/api" "log" ) var conn *dbus.Conn var sDbus *StreamDeckDBus +var sDInfo api.StreamDeckInfo type StreamDeckDBus struct { - Cols int `json:"cols,omitempty"` - Rows int `json:"rows,omitempty"` - IconSize int `json:"icon_size,omitempty"` - Page int `json:"page"` } func (s StreamDeckDBus) GetDeckInfo() (string, *dbus.Error) { @@ -72,7 +70,8 @@ func InitDBUS() error { } defer conn.Close() - sDbus = &StreamDeckDBus{ + sDbus = &StreamDeckDBus{} + sDInfo = api.StreamDeckInfo{ Page: p, } conn.ExportAll(sDbus, "/com/unixstreamdeck/streamdeckd", "com.unixstreamdeck.streamdeckd") @@ -93,6 +92,6 @@ func EmitPage(page int) { conn.Emit("/com/unixstreamdeck/streamdeckd", "com.unixstreamdeck.streamdeckd.Page", page) } if sDbus != nil { - sDbus.Page = page + sDInfo.Page = page } } diff --git a/handlers/counter.go b/handlers/counter.go index d1e543e..f733e06 100644 --- a/handlers/counter.go +++ b/handlers/counter.go @@ -3,12 +3,16 @@ package handlers import ( "github.com/fogleman/gg" "github.com/unix-streamdeck/api" - "github.com/unix-streamdeck/driver" "golang.org/x/image/font/inconsolata" + "image" "strconv" + "time" ) -func (c *CounterIconHandler) Icon(page int, index int, key *api.Key, dev streamdeck.Device) { +func (c *CounterIconHandler) Icon(key *api.Key, _ api.StreamDeckInfo, callback func(image image.Image)) { + if c.Callback == nil { + c.Callback = callback + } if c.Running { img := gg.NewContext(72, 72) img.SetRGB(0, 0, 0) @@ -18,8 +22,9 @@ func (c *CounterIconHandler) Icon(page int, index int, key *api.Key, dev streamd Count := strconv.Itoa(c.Count) img.DrawStringAnchored(Count, 72/2, 72/2, 0.5, 0.5) img.Clip() - c.OnSetImage(img.Image(), index, page, dev) + callback(img.Image()) key.Buff = img.Image() + time.Sleep(250 * time.Millisecond) } } @@ -29,11 +34,13 @@ func (c CounterIconHandler) Stop() { type CounterKeyHandler struct{} -func (CounterKeyHandler) Key(page int, index int, key *api.Key, dev streamdeck.Device) { +func (CounterKeyHandler) Key(key *api.Key, info api.StreamDeckInfo) { if key.IconHandler != "Counter" { return } handler := key.IconHandlerStruct.(*CounterIconHandler) handler.Count += 1 - handler.Icon(page, index, key, dev) + if handler.Callback != nil { + handler.Icon(key, info, handler.Callback) + } } diff --git a/handlers/gif.go b/handlers/gif.go index 58cbd0c..1224c0b 100644 --- a/handlers/gif.go +++ b/handlers/gif.go @@ -3,7 +3,6 @@ package handlers import ( "github.com/nfnt/resize" "github.com/unix-streamdeck/api" - "github.com/unix-streamdeck/driver" "image" "image/gif" "log" @@ -11,7 +10,7 @@ import ( "time" ) -func (s *GifIconHandler) Icon(page int, index int, key *api.Key, dev streamdeck.Device) { +func (s *GifIconHandler) Icon(key *api.Key, info api.StreamDeckInfo, callback func(image image.Image)) { s.Running = true f, err := os.Open(key.Icon) if err != nil { @@ -26,20 +25,20 @@ func (s *GifIconHandler) Icon(page int, index int, key *api.Key, dev streamdeck. timeDelay := gifs.Delay[0] frames := make([]image.Image, len(gifs.Image)) for i, frame := range gifs.Image { - frames[i] = resize.Resize(dev.Pixels, dev.Pixels, frame, resize.Lanczos3) + frames[i] = resize.Resize(uint(info.IconSize), uint(info.IconSize), frame, resize.Lanczos3) } - go loop(frames, timeDelay, page, index, dev, key, s) + go loop(frames, timeDelay, callback, key, s) } func (s *GifIconHandler) Stop() { s.Running = false } -func loop(frames []image.Image, timeDelay int, page int, index int, dev streamdeck.Device, key *api.Key, s *GifIconHandler) { +func loop(frames []image.Image, timeDelay int, callback func(image image.Image), key *api.Key, s *GifIconHandler) { gifIndex := 0 for s.Running { img := frames[gifIndex] - s.OnSetImage(img, index, page, dev) + callback(img) key.Buff = img gifIndex++ if gifIndex >= len(frames) { diff --git a/handlers/handlers.go b/handlers/handlers.go index 567ec13..35f3735 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -1,23 +1,18 @@ package handlers -import ( - "image" - "github.com/unix-streamdeck/driver" -) +import "image" type CounterIconHandler struct { Count int Running bool - OnSetImage func(img image.Image, i int, page int, dev streamdeck.Device) + Callback func(image image.Image) } type GifIconHandler struct { Running bool - OnSetImage func(img image.Image, i int, page int, dev streamdeck.Device) } type TimeIconHandler struct{ Running bool - OnSetImage func(img image.Image, i int, page int, dev streamdeck.Device) } diff --git a/handlers/time.go b/handlers/time.go index 81e9180..7d989cd 100644 --- a/handlers/time.go +++ b/handlers/time.go @@ -3,43 +3,34 @@ package handlers import ( "github.com/fogleman/gg" "github.com/unix-streamdeck/api" - "github.com/unix-streamdeck/driver" "golang.org/x/image/font/inconsolata" - "strconv" + "image" "time" ) -func (t *TimeIconHandler) Icon(page int, index int, key *api.Key, dev streamdeck.Device) { +func (t *TimeIconHandler) Icon(key *api.Key, info api.StreamDeckInfo, callback func(image image.Image)) { t.Running = true - go timeLoop(page, index, dev, key, t) + go timeLoop(key, info, callback, t) } func (t *TimeIconHandler) Stop() { t.Running = false } -func timeLoop(page int, index int, dev streamdeck.Device, key *api.Key, handler *TimeIconHandler) { +func timeLoop(key *api.Key, info api.StreamDeckInfo, callback func(image image.Image), handler *TimeIconHandler) { for handler.Running { - img := gg.NewContext(72, 72) + img := gg.NewContext(info.IconSize, info.IconSize) img.SetRGB(0, 0, 0) img.Clear() img.SetRGB(1, 1, 1) img.SetFontFace(inconsolata.Regular8x16) t := time.Now() tString := t.Format("15:04:05") - img.DrawStringAnchored(tString, 72/2, 72/2, 0.5, 0.5) + img.DrawStringAnchored(tString, float64(info.IconSize)/2, float64(info.IconSize)/2, 0.5, 0.5) img.Clip() - handler.OnSetImage(img.Image(), index, page, dev) + callback(img.Image()) key.Buff = img.Image() time.Sleep(time.Second) } -} - -func zeroes(i int) (string) { - if i < 10 { - return "0" + strconv.Itoa(i) - } else { - return strconv.Itoa(i) - } } \ No newline at end of file diff --git a/interface.go b/interface.go index 3c79a89..a023af2 100644 --- a/interface.go +++ b/interface.go @@ -5,7 +5,6 @@ import ( "github.com/fogleman/gg" "github.com/nfnt/resize" "github.com/unix-streamdeck/api" - "github.com/unix-streamdeck/driver" "github.com/unix-streamdeck/streamdeckd/handlers" "golang.org/x/image/font/inconsolata" "golang.org/x/sync/semaphore" @@ -39,7 +38,7 @@ func ResizeImage(img image.Image) image.Image { return resize.Resize(dev.Pixels, dev.Pixels, img, resize.Lanczos3) } -func SetImage(img image.Image, i int, page int, _ streamdeck.Device) { +func SetImage(img image.Image, i int, page int) { ctx := context.Background() err := sem.Acquire(ctx, 1) if err != nil { @@ -83,7 +82,7 @@ func SetKeyImage(currentKey *api.Key, i int) { } } if currentKey.Buff != nil { - SetImage(currentKey.Buff, i, p, dev) + SetImage(currentKey.Buff, i, p) } } @@ -92,12 +91,12 @@ func SetPage(config *api.Config, page int) { currentPage := config.Pages[page] for i := 0; i < len(currentPage); i++ { currentKey := ¤tPage[i] - go SetKey(currentKey, i, page, dev) + go SetKey(currentKey, i, page) } EmitPage(p) } -func SetKey(currentKey *api.Key, i int, page int, dev streamdeck.Device) { +func SetKey(currentKey *api.Key, i int, page int) { if currentKey.Buff == nil { if currentKey.IconHandler == "" { SetKeyImage(currentKey, i) @@ -105,24 +104,26 @@ func SetKey(currentKey *api.Key, i int, page int, dev streamdeck.Device) { } else if currentKey.IconHandlerStruct == nil { var handler api.IconHandler if currentKey.IconHandler == "Gif" { - handler = &handlers.GifIconHandler{Running:true, OnSetImage: SetImage} + handler = &handlers.GifIconHandler{Running:true} } else if currentKey.IconHandler == "Counter" { - handler = &handlers.CounterIconHandler{Count:0, Running: true, OnSetImage: SetImage} + handler = &handlers.CounterIconHandler{Count:0, Running: true} } else if currentKey.IconHandler == "Time" { - handler = &handlers.TimeIconHandler{Running:true, OnSetImage: SetImage} + handler = &handlers.TimeIconHandler{Running:true} } if handler == nil { return } - handler.Icon(page, i, currentKey, dev) + handler.Icon(currentKey, sDInfo, func(image image.Image) { + SetImage(image, i, page) + }) currentKey.IconHandlerStruct = handler } } else { - SetImage(currentKey.Buff, i, p, dev) + SetImage(currentKey.Buff, i, p) } } -func HandleInput(key *api.Key, page int, index int) { +func HandleInput(key *api.Key, page int) { if key.Command != "" { runCommand(key.Command) } @@ -153,7 +154,7 @@ func HandleInput(key *api.Key, page int, index int) { } key.KeyHandlerStruct = handler } - key.KeyHandlerStruct.Key(page, index, key, streamdeck.Device{}) + key.KeyHandlerStruct.Key(key, sDInfo) } } @@ -171,7 +172,7 @@ func Listen() { } if k.Pressed == true { if len(config.Pages)-1 >= p && len(config.Pages[p])-1 >= int(k.Index) { - HandleInput(&config.Pages[p][k.Index], p, int(k.Index)) + HandleInput(&config.Pages[p][k.Index], p) } } } diff --git a/main.go b/main.go index 9956d7c..2912a52 100644 --- a/main.go +++ b/main.go @@ -68,9 +68,9 @@ func attemptConnection() { if isOpen { SetPage(config, p) if sDbus != nil { - sDbus.IconSize = int(dev.Pixels) - sDbus.Rows = int(dev.Rows) - sDbus.Cols = int(dev.Columns) + sDInfo.IconSize = int(dev.Pixels) + sDInfo.Rows = int(dev.Rows) + sDInfo.Cols = int(dev.Columns) } Listen() } From d67c5653072436f1d66fe8232ba7a1f7eeade6be Mon Sep 17 00:00:00 2001 From: The-Jonsey Date: Thu, 27 Aug 2020 17:26:47 +0100 Subject: [PATCH 08/10] Removed key pointer in handlers --- handlers/counter.go | 5 ++--- handlers/gif.go | 7 +++---- handlers/handlers.go | 7 +++---- handlers/time.go | 7 +++---- interface.go | 5 +++-- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/handlers/counter.go b/handlers/counter.go index f733e06..5a652ce 100644 --- a/handlers/counter.go +++ b/handlers/counter.go @@ -9,7 +9,7 @@ import ( "time" ) -func (c *CounterIconHandler) Icon(key *api.Key, _ api.StreamDeckInfo, callback func(image image.Image)) { +func (c *CounterIconHandler) Icon(_ api.Key, _ api.StreamDeckInfo, callback func(image image.Image)) { if c.Callback == nil { c.Callback = callback } @@ -23,7 +23,6 @@ func (c *CounterIconHandler) Icon(key *api.Key, _ api.StreamDeckInfo, callback f img.DrawStringAnchored(Count, 72/2, 72/2, 0.5, 0.5) img.Clip() callback(img.Image()) - key.Buff = img.Image() time.Sleep(250 * time.Millisecond) } } @@ -34,7 +33,7 @@ func (c CounterIconHandler) Stop() { type CounterKeyHandler struct{} -func (CounterKeyHandler) Key(key *api.Key, info api.StreamDeckInfo) { +func (CounterKeyHandler) Key(key api.Key, info api.StreamDeckInfo) { if key.IconHandler != "Counter" { return } diff --git a/handlers/gif.go b/handlers/gif.go index 1224c0b..4d3bb3e 100644 --- a/handlers/gif.go +++ b/handlers/gif.go @@ -10,7 +10,7 @@ import ( "time" ) -func (s *GifIconHandler) Icon(key *api.Key, info api.StreamDeckInfo, callback func(image image.Image)) { +func (s *GifIconHandler) Icon(key api.Key, info api.StreamDeckInfo, callback func(image image.Image)) { s.Running = true f, err := os.Open(key.Icon) if err != nil { @@ -27,19 +27,18 @@ func (s *GifIconHandler) Icon(key *api.Key, info api.StreamDeckInfo, callback fu for i, frame := range gifs.Image { frames[i] = resize.Resize(uint(info.IconSize), uint(info.IconSize), frame, resize.Lanczos3) } - go loop(frames, timeDelay, callback, key, s) + go loop(frames, timeDelay, callback, s) } func (s *GifIconHandler) Stop() { s.Running = false } -func loop(frames []image.Image, timeDelay int, callback func(image image.Image), key *api.Key, s *GifIconHandler) { +func loop(frames []image.Image, timeDelay int, callback func(image image.Image), s *GifIconHandler) { gifIndex := 0 for s.Running { img := frames[gifIndex] callback(img) - key.Buff = img gifIndex++ if gifIndex >= len(frames) { gifIndex = 0 diff --git a/handlers/handlers.go b/handlers/handlers.go index 35f3735..d7a3f22 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -3,8 +3,8 @@ package handlers import "image" type CounterIconHandler struct { - Count int - Running bool + Count int + Running bool Callback func(image image.Image) } @@ -12,7 +12,6 @@ type GifIconHandler struct { Running bool } -type TimeIconHandler struct{ +type TimeIconHandler struct { Running bool } - diff --git a/handlers/time.go b/handlers/time.go index 7d989cd..c1adfee 100644 --- a/handlers/time.go +++ b/handlers/time.go @@ -9,16 +9,16 @@ import ( ) -func (t *TimeIconHandler) Icon(key *api.Key, info api.StreamDeckInfo, callback func(image image.Image)) { +func (t *TimeIconHandler) Icon(_ api.Key, info api.StreamDeckInfo, callback func(image image.Image)) { t.Running = true - go timeLoop(key, info, callback, t) + go timeLoop(info, callback, t) } func (t *TimeIconHandler) Stop() { t.Running = false } -func timeLoop(key *api.Key, info api.StreamDeckInfo, callback func(image image.Image), handler *TimeIconHandler) { +func timeLoop(info api.StreamDeckInfo, callback func(image image.Image), handler *TimeIconHandler) { for handler.Running { img := gg.NewContext(info.IconSize, info.IconSize) img.SetRGB(0, 0, 0) @@ -30,7 +30,6 @@ func timeLoop(key *api.Key, info api.StreamDeckInfo, callback func(image image.I img.DrawStringAnchored(tString, float64(info.IconSize)/2, float64(info.IconSize)/2, 0.5, 0.5) img.Clip() callback(img.Image()) - key.Buff = img.Image() time.Sleep(time.Second) } } \ No newline at end of file diff --git a/interface.go b/interface.go index a023af2..539f7df 100644 --- a/interface.go +++ b/interface.go @@ -113,8 +113,9 @@ func SetKey(currentKey *api.Key, i int, page int) { if handler == nil { return } - handler.Icon(currentKey, sDInfo, func(image image.Image) { + handler.Icon(*currentKey, sDInfo, func(image image.Image) { SetImage(image, i, page) + currentKey.Buff = image }) currentKey.IconHandlerStruct = handler } @@ -154,7 +155,7 @@ func HandleInput(key *api.Key, page int) { } key.KeyHandlerStruct = handler } - key.KeyHandlerStruct.Key(key, sDInfo) + key.KeyHandlerStruct.Key(*key, sDInfo) } } From 7737f2525880b0f33c6f426f4b62d5695fd71e66 Mon Sep 17 00:00:00 2001 From: The-Jonsey Date: Thu, 27 Aug 2020 18:01:35 +0100 Subject: [PATCH 09/10] Refactored remounting handlers --- handlers/counter.go | 12 ++++++++++-- handlers/gif.go | 10 +++++++++- handlers/time.go | 10 +++++++++- interface.go | 9 ++++++++- main.go | 2 -- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/handlers/counter.go b/handlers/counter.go index 5a652ce..a0c1e59 100644 --- a/handlers/counter.go +++ b/handlers/counter.go @@ -9,7 +9,7 @@ import ( "time" ) -func (c *CounterIconHandler) Icon(_ api.Key, _ api.StreamDeckInfo, callback func(image image.Image)) { +func (c *CounterIconHandler) Start(_ api.Key, _ api.StreamDeckInfo, callback func(image image.Image)) { if c.Callback == nil { c.Callback = callback } @@ -27,6 +27,14 @@ func (c *CounterIconHandler) Icon(_ api.Key, _ api.StreamDeckInfo, callback func } } +func (c *CounterIconHandler) IsRunning() bool { + return c.Running +} + +func (c *CounterIconHandler) SetRunning(running bool) { + c.Running = running +} + func (c CounterIconHandler) Stop() { c.Running = false } @@ -40,6 +48,6 @@ func (CounterKeyHandler) Key(key api.Key, info api.StreamDeckInfo) { handler := key.IconHandlerStruct.(*CounterIconHandler) handler.Count += 1 if handler.Callback != nil { - handler.Icon(key, info, handler.Callback) + handler.Start(key, info, handler.Callback) } } diff --git a/handlers/gif.go b/handlers/gif.go index 4d3bb3e..d0ff4b4 100644 --- a/handlers/gif.go +++ b/handlers/gif.go @@ -10,7 +10,7 @@ import ( "time" ) -func (s *GifIconHandler) Icon(key api.Key, info api.StreamDeckInfo, callback func(image image.Image)) { +func (s *GifIconHandler) Start(key api.Key, info api.StreamDeckInfo, callback func(image image.Image)) { s.Running = true f, err := os.Open(key.Icon) if err != nil { @@ -30,6 +30,14 @@ func (s *GifIconHandler) Icon(key api.Key, info api.StreamDeckInfo, callback fun go loop(frames, timeDelay, callback, s) } +func (s *GifIconHandler) IsRunning() bool { + return s.Running +} + +func (s *GifIconHandler) SetRunning(running bool) { + s.Running = running +} + func (s *GifIconHandler) Stop() { s.Running = false } diff --git a/handlers/time.go b/handlers/time.go index c1adfee..a7595eb 100644 --- a/handlers/time.go +++ b/handlers/time.go @@ -9,11 +9,19 @@ import ( ) -func (t *TimeIconHandler) Icon(_ api.Key, info api.StreamDeckInfo, callback func(image image.Image)) { +func (t *TimeIconHandler) Start(_ api.Key, info api.StreamDeckInfo, callback func(image image.Image)) { t.Running = true go timeLoop(info, callback, t) } +func (t *TimeIconHandler) IsRunning() bool { + return t.Running +} + +func (t *TimeIconHandler) SetRunning(running bool) { + t.Running = running +} + func (t *TimeIconHandler) Stop() { t.Running = false } diff --git a/interface.go b/interface.go index 539f7df..b977f07 100644 --- a/interface.go +++ b/interface.go @@ -113,7 +113,7 @@ func SetKey(currentKey *api.Key, i int, page int) { if handler == nil { return } - handler.Icon(*currentKey, sDInfo, func(image image.Image) { + handler.Start(*currentKey, sDInfo, func(image image.Image) { SetImage(image, i, page) currentKey.Buff = image }) @@ -122,6 +122,13 @@ func SetKey(currentKey *api.Key, i int, page int) { } else { SetImage(currentKey.Buff, i, p) } + if currentKey.IconHandlerStruct != nil && !currentKey.IconHandlerStruct.IsRunning() { + currentKey.IconHandlerStruct.SetRunning(true) + currentKey.IconHandlerStruct.Start(*currentKey, sDInfo, func(image image.Image) { + SetImage(image, i, page) + currentKey.Buff = image + }) + } } func HandleInput(key *api.Key, page int) { diff --git a/main.go b/main.go index 2912a52..54c99da 100644 --- a/main.go +++ b/main.go @@ -210,8 +210,6 @@ func unmountHandlers() { key := &page[i2] if key.IconHandlerStruct != nil { key.IconHandlerStruct.Stop() - key.IconHandlerStruct = nil - key.Buff = nil } } } From 1b17e171ea64fdf1e14d6f54294c04959c93a3da Mon Sep 17 00:00:00 2001 From: The-Jonsey Date: Fri, 28 Aug 2020 01:06:27 +0100 Subject: [PATCH 10/10] Updated unix-streamdeck/api version --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 20ebc75..b5898cf 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/godbus/dbus/v5 v5.0.4-0.20200513180336-df5ef3eb7cca github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 - github.com/unix-streamdeck/api v0.0.0-20200818180846-6942d99617b2 + github.com/unix-streamdeck/api v0.0.0-20200828000516-c734a9f6cec5 github.com/unix-streamdeck/driver v0.0.0-20200817173808-cdaf123c076b golang.org/x/image v0.0.0-20200119044424-58c23975cae1 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 diff --git a/go.sum b/go.sum index cf3def9..5dc5f37 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/unix-streamdeck/api v0.0.0-20200818180846-6942d99617b2 h1:du+OoTUOp1mf/VRdQ8xQMWdR6JrOGbZvDG1nb9BBxHM= -github.com/unix-streamdeck/api v0.0.0-20200818180846-6942d99617b2/go.mod h1:rweAXRgCWdCACCuVhmleidq7HnJEO38zBGDe8uQqZ0w= +github.com/unix-streamdeck/api v0.0.0-20200828000516-c734a9f6cec5 h1:8WlgvTJMHvfxqmQYyTbfM9TL/BYIm/WfrbDhyA8ihQo= +github.com/unix-streamdeck/api v0.0.0-20200828000516-c734a9f6cec5/go.mod h1:rweAXRgCWdCACCuVhmleidq7HnJEO38zBGDe8uQqZ0w= github.com/unix-streamdeck/driver v0.0.0-20200817173808-cdaf123c076b h1:27gVti9+OevmBC2BnWlKC0dQ0eiIHh7PvYTWxt4vb6A= github.com/unix-streamdeck/driver v0.0.0-20200817173808-cdaf123c076b/go.mod h1:i3Eg6kJBslgUk2VIPJ3Cclta2fpV1KJrOnOnR8gnVKY= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=