OS/src/skillerctl.c
2019-01-07 22:17:14 +01:00

133 lines
3.6 KiB
C

/**
* Ten program jest napisany bardziej w postaci PoC niż faktycznej aplikacji użytkowej - stąd brak jakiejkolwiek walidacji inputu użytkownika.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "skiller.h"
#include "usb.h"
#include "utils.h"
#define PACKETS_MAX 255
skillerctl_packet_t packets[255] = {};
size_t count = 0;
char *input_pop_arg(int *i, int argc, char **argv)
{
if (++*i >= argc) {
return NULL;
}
return argv[*i];
}
size_t handle_input(int argc, char **argv)
{
char *arg;
int i = 0;
while ((arg = input_pop_arg(&i, argc, argv))) {
skillerctl_packet_t *current = packets + count;
if (strcmp(arg, "-d") == 0) {
printf("Disable leds.\n");
skillerctl_disable_led_command(current);
count++;
} else if (strcmp(arg, "-e") == 0) {
printf("Enable leds.\n");
skillerctl_enable_led_command(current);
count++;
} else if (strcmp(arg, "-c") == 0) {
char *keys = input_pop_arg(&i, argc, argv);
uint32_t color = strtol(input_pop_arg(&i, argc, argv), NULL, 16);
keys = strtok(keys, ",");
do {
skillerctl_keyaddr_t addr = skillerctl_keyaddr(keys);
printf("Set key %s [%04xh] color to #%06x.\n", skillerctl_keystr(addr), addr, color);
skillerctl_color_command(packets + count++, addr, color);
} while ((keys = strtok(NULL, ",")));
} else if (strcmp(arg, "-C") == 0) {
uint32_t color = strtol(input_pop_arg(&i, argc, argv), NULL, 16);
printf("Clear to #%06x.\n", color);
uint32_t colors[18] = {};
for (int i = 0; i < 18; i++) colors[i] = color;
for (int i = 0; i <= SK_LIMIT_KEY / 54; i++) {
skillerctl_color_batch_command(packets + count++, 54*i, colors, 18);
}
} else if (strcmp(arg, "-b") == 0) {
uint8_t brightness = strtol(input_pop_arg(&i, argc, argv), NULL, 10);
printf("Set brightness to %d.\n", brightness);
skillerctl_set_brightness_command(current, brightness);
count++;
} else if (strcmp(arg, "-m") == 0) {
skillerctl_mode_t mode = skillerctl_strmode(input_pop_arg(&i, argc, argv));
if (mode == 0xFF) {
continue;
}
printf("Set mode to to %s [%02xh].\n", skillerctl_modestr(mode), mode);
skillerctl_set_mode_command(current, mode);
count++;
} else {
printf("Unknown command %s, omiting.\n", arg);
continue;
}
}
return count;
}
void handle_logic(libusb_device *skiller)
{
libusb_device_handle *handle;
skillerctl_packet_t packet;
if (skiller == NULL) {
printf("Cannot found compatibile keyboard, is it connected?\n");
return;
}
if (libusb_open(skiller, &handle) != LIBUSB_SUCCESS) {
printf("Cannot open device, try with sudo.\n");
return;
}
libusb_detach_kernel_driver(handle, 1);
libusb_claim_interface(handle, 1);
for (int i = 0; i < count; i++) {
skillerctl_send_command(handle, packets + i);
}
libusb_release_interface(handle, 1);
libusb_attach_kernel_driver(handle, 1);
libusb_close(handle);
}
int main(int argc, char **argv)
{
libusb_device **list;
libusb_init(NULL);
size_t count = libusb_get_device_list(NULL, &list);
libusb_device *skiller = skillerctl_find_device(list, count);
handle_input(argc, argv);
handle_logic(skiller);
libusb_free_device_list(list, 1);
libusb_exit(NULL);
}