Skip to content

Commit

Permalink
bulk:
Browse files Browse the repository at this point in the history
- m55
- m55 wireless
- m55 rgb pro
  • Loading branch information
jurkovic-nikola committed Dec 14, 2024
1 parent 4edc6e2 commit bc57d68
Show file tree
Hide file tree
Showing 17 changed files with 3,950 additions and 85 deletions.
108 changes: 55 additions & 53 deletions README.md

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions database/devices.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,18 @@
{
"productId": "1bdb",
"kernel": ""
},
{
"productId": "2b03",
"kernel": "hidraw*"
},
{
"productId": "2b00",
"kernel": ""
},
{
"productId": "1b70",
"kernel": "hidraw*"
}
]
}
Expand Down
24 changes: 22 additions & 2 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash

set -e
USER_TO_CHECK="openlinkhub"
Expand Down Expand Up @@ -87,16 +87,36 @@ EOM
echo "Running systemctl daemon-reload"
sudo systemctl daemon-reload

echo "Cleanup..."
sudo rm -f /etc/udev/rules.d/99-corsair-*.rules

echo "Setting udev device permissions..."
lsusb -d 1b1c: | while read -r line; do
ids=$(echo "$line" | awk '{print $6}')
vendor_id=$(echo "$ids" | cut -d':' -f1)
device_id=$(echo "$ids" | cut -d':' -f2)

match=false
usb_array=("1bc5" "2b10" "2b07" "1bfd" "1bfe" "1be3" "1bdb" "1bdc" "1ba6")
for hex in "${usb_array[@]}"; do
if [ "$hex" == "$device_id" ]; then
match=true
break
fi
done

if [ "$match" = true ]; then
cat > /etc/udev/rules.d/99-corsair-"$device_id".rules <<- EOM
KERNEL=="hidraw*", SUBSYSTEMS=="usb", ATTRS{idVendor}=="$vendor_id", ATTRS{idProduct}=="$device_id", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="$vendor_id", ATTRS{idProduct}=="$device_id", MODE="0600", OWNER="$USER_TO_CHECK"
EOM
else
cat > /etc/udev/rules.d/99-corsair-"$device_id".rules <<- EOM
KERNEL=="hidraw*", SUBSYSTEMS=="usb", ATTRS{idVendor}=="$vendor_id", ATTRS{idProduct}=="$device_id", MODE="0600", OWNER="$USER_TO_CHECK"
EOM
fi
done


echo "Reloading udev..."
sudo udevadm control --reload-rules
sudo udevadm trigger
Expand Down
66 changes: 63 additions & 3 deletions src/devices/devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import (
"OpenLinkHub/src/devices/lnpro"
"OpenLinkHub/src/devices/lsh"
"OpenLinkHub/src/devices/lt100"
"OpenLinkHub/src/devices/m55"
"OpenLinkHub/src/devices/m55W"
"OpenLinkHub/src/devices/m55rgbpro"
"OpenLinkHub/src/devices/memory"
"OpenLinkHub/src/devices/mm700"
"OpenLinkHub/src/devices/nightsabreW"
Expand Down Expand Up @@ -73,6 +76,9 @@ const (
productTypeScimitarRgbElite = 207
productTypeScimitarRgbEliteW = 208
productTypeScimitarRgbEliteWU = 209
productTypeM55 = 210
productTypeM55W = 211
productTypeM55RgbPro = 212
productTypeST100 = 401
productTypeMM700 = 402
productTypeLT100 = 403
Expand Down Expand Up @@ -107,9 +113,9 @@ var (
devices = make(map[string]*Device, 0)
products = make(map[string]Product, 0)
keyboards = []uint16{7127, 7165, 7166, 7110, 7083, 11024, 11015, 7109, 7091}
mouses = []uint16{7059, 7005, 6988, 7096, 7139, 7131}
mouses = []uint16{7059, 7005, 6988, 7096, 7139, 7131, 11011, 7024}
pads = []uint16{7067}
dongles = []uint16{7132, 7078}
dongles = []uint16{7132, 7078, 11008}
)

// Stop will stop all active devices
Expand Down Expand Up @@ -1265,7 +1271,7 @@ func Init() {
}
}(vendorId, productId, key)
}
case 7132, 7078: // Corsair SLIPSTREAM WIRELESS USB Receiver
case 7132, 7078, 11008: // Corsair SLIPSTREAM WIRELESS USB Receiver
{
go func(vendorId, productId uint16, key string) {
dev := slipstream.Init(vendorId, productId, key)
Expand All @@ -1279,6 +1285,26 @@ func Init() {
}
for _, value := range dev.Devices {
switch value.ProductId {
case 7163:
{
d := m55W.Init(
value.VendorId,
productId,
value.ProductId,
dev.GetDevice(),
value.Endpoint,
value.Serial,
)
devices[d.Serial] = &Device{
ProductType: productTypeM55W,
Product: "M55 WIRELESS",
Serial: d.Serial,
Firmware: d.Firmware,
Image: "icon-mouse.svg",
Instance: d,
}
dev.AddPairedDevice(value.ProductId, d)
}
case 7131:
{
d := scimitarW.Init(
Expand Down Expand Up @@ -1545,6 +1571,40 @@ func Init() {
}
}(vendorId, productId, key)
}
case 11011: // CORSAIR M55 Gaming Mouse
{
go func(vendorId, productId uint16, key string) {
dev := m55.Init(vendorId, productId, key)
if dev == nil {
return
}
devices[dev.Serial] = &Device{
ProductType: productTypeM55,
Product: dev.Product,
Serial: dev.Serial,
Firmware: dev.Firmware,
Image: "icon-mouse.svg",
Instance: dev,
}
}(vendorId, productId, key)
}
case 7024: // CORSAIR M55 RGB PRO Gaming Mouse
{
go func(vendorId, productId uint16, key string) {
dev := m55rgbpro.Init(vendorId, productId, key)
if dev == nil {
return
}
devices[dev.Serial] = &Device{
ProductType: productTypeM55RgbPro,
Product: dev.Product,
Serial: dev.Serial,
Firmware: dev.Firmware,
Image: "icon-mouse.svg",
Instance: dev,
}
}(vendorId, productId, key)
}
case 0: // Memory
{
go func(serialId string) {
Expand Down
3 changes: 2 additions & 1 deletion src/devices/k65plus/k65plus.go
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,8 @@ func (d *Device) controlDialListener() {
logger.Log(logger.Fields{"error": err, "serial": d.Serial}).Error("Error reading data")
break
}

fmt.Println(time.Now(), data)
value := data[4]
switch d.DeviceProfile.ControlDial {
case 1:
Expand Down Expand Up @@ -1349,7 +1351,6 @@ func (d *Device) controlDialListener() {
}
}
}
time.Sleep(10 * time.Millisecond)
}
}()
}
1 change: 0 additions & 1 deletion src/devices/k65plusW/k65plusW.go
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,6 @@ func (d *Device) controlDialListener() {
}
}
}
time.Sleep(40 * time.Millisecond)
}
}()
}
136 changes: 123 additions & 13 deletions src/devices/lcd/lcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ import (
"golang.org/x/image/font/opentype"
"image"
"image/color"
"image/gif"
"image/jpeg"
"os"
"regexp"
"slices"
"strconv"
"strings"
"sync"
)

Expand All @@ -42,22 +45,30 @@ const (
)

var (
pwd, _ = os.Getwd()
location = pwd + "/static/img/lcd/background.jpg"
fontLocation = pwd + "/static/fonts/teko.ttf"
mutex sync.Mutex
imgWidth = 480
imgHeight = 480
lcdDevices = map[string]uint16{}
vendorId uint16 = 6940 // Corsair
pwd, _ = os.Getwd()
location = pwd + "/static/img/lcd/background.jpg"
animationsPath = pwd + "/static/img/lcd/animations/"
fontLocation = pwd + "/static/fonts/teko.ttf"
mutex sync.Mutex
imgWidth = 480
imgHeight = 480
lcdDevices = map[string]uint16{}
vendorId uint16 = 6940 // Corsair
)

type Animations struct {
Name string
Frames int
Buffer [][]byte
}

type LCD struct {
image image.Image
font *truetype.Font
fontBytes []byte
sfntFont *opentype.Font
Devices []Device
image image.Image
font *truetype.Font
fontBytes []byte
sfntFont *opentype.Font
Devices []Device
Animations []Animations
}

type Device struct {
Expand Down Expand Up @@ -115,9 +126,108 @@ func Init() {
sfntFont: sfntFont,
}
lcd = *lcdData
loadAnimations()
loadLcdDevices()
}

func loadAnimations() {
m := 0
logger.Log(logger.Fields{}).Info("Loading LCD animation images")
files, err := os.ReadDir(animationsPath)
if err != nil {
logger.Log(logger.Fields{"error": err, "location": animationsPath}).Error("Unable to read content of a folder")
return
}
for _, fi := range files {
// Define a full path of filename
imagePath := animationsPath + fi.Name()

// Check if filename has .json extension
if !common.IsValidExtension(imagePath, ".gif") {
logger.Log(logger.Fields{"error": err, "location": animationsPath, "image": imagePath}).Warn("Image needs to have .gif extension")
continue
}

// Process filename
fileName := strings.Split(fi.Name(), ".")[0]
if m, _ := regexp.MatchString("^[a-zA-Z0-9]+$", fileName); !m {
logger.Log(logger.Fields{"error": err, "location": animationsPath, "image": imagePath}).Warn("Image name can only have letters and numbers. Please rename your image")
continue
}

// Open image
file, err := os.Open(imagePath)
if err != nil {
logger.Log(logger.Fields{"error": err, "location": animationsPath, "image": imagePath}).Warn("Unable to open gif animation")
continue
}

// Decode image
g, err := gif.DecodeAll(file)
if err != nil {
logger.Log(logger.Fields{"error": err, "location": animationsPath, "image": imagePath}).Warn("Error decoding gif animation")
return
}

frames := len(g.Image)
imageBuffer := make([][]byte, frames) // Slice to store each frame's byte slice

resizedGIF := &gif.GIF{
LoopCount: g.LoopCount,
}
for i, frame := range g.Image {
// Convert frame to RGBA to support resizing
bounds := frame.Bounds()
palettedImage := image.NewPaletted(image.Rect(0, 0, imgWidth, imgHeight), frame.Palette)
draw.Draw(palettedImage, palettedImage.Rect, resizeImage(frame, imgWidth, imgHeight), bounds.Min, draw.Src)

// Append the resized frame to the new GIF
resizedGIF.Image = append(resizedGIF.Image, palettedImage)
resizedGIF.Delay = append(resizedGIF.Delay, g.Delay[0])

// Create a buffer to encode the frame
var buffer bytes.Buffer
// Encode the frame back into a GIF
err = jpeg.Encode(&buffer, palettedImage, nil)
if err != nil {
logger.Log(logger.Fields{"error": err, "location": animationsPath, "image": imagePath, "frame": i}).Warn("Failed to encode image frame")
continue
}

// Store the byte slice for the frame
imageBuffer[i] = buffer.Bytes()
}
animation := &Animations{
Name: fileName,
Frames: frames,
Buffer: imageBuffer,
}
lcd.Animations = append(lcd.Animations, *animation)
m++
}
imgText := "image"
if m > 1 {
imgText = "images"
}
logger.Log(logger.Fields{"amount": m}).Info(fmt.Sprintf("Loaded %v LCD animation %s", m, imgText))
}

// resizeImage will resize image with given width and height
func resizeImage(src image.Image, width, height int) image.Image {
dst := image.NewRGBA(image.Rect(0, 0, width, height))
srcBounds := src.Bounds()

// Simple nearest-neighbor resizing
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
srcX := srcBounds.Min.X + x*srcBounds.Dx()/width
srcY := srcBounds.Min.Y + y*srcBounds.Dy()/height
dst.Set(x, y, src.At(srcX, srcY))
}
}
return dst
}

func loadLcdDevices() {
lcdProductIds := []uint16{3150, 3139, 3129}

Expand Down
Loading

0 comments on commit bc57d68

Please sign in to comment.