// SPDX-License-Identifier: GPL-2.0 /* * Hidraw Userspace Example * * Copyright (c) 2010 Alan Ott * Copyright (c) 2010 Signal 11 Software * * The code may be used by anyone for any purpose, * and can serve as a starting point for developing * applications using hidraw. */ /* Linux */ #include #include #include /* Unix */ #include #include #include #include #include /* C */ #include #include #include #include #include typedef struct { uint8_t r; uint8_t g; uint8_t b; } C; #define N_LEDS 9 static unsigned map[N_LEDS]={2,1,0,3,4,5,8,7,6}; C current[N_LEDS]; C last[N_LEDS]; void sync_leds (int fd) { unsigned i; uint8_t buf[8]; for (i = 0; i < N_LEDS; ++i) { /* Send a Report to the Device */ if ((last[i].r != current[i].r) || (last[i].g != current[i].g) || (last[i].b != current[i].b)) { buf[0] = 0x05; buf[1] = map[i]; buf[2] = current[i].r; buf[3] = current[i].g; buf[4] = current[i].b; write (fd, buf, 8); last[i] = current[i]; } } } unsigned f(int v) { v-=5; if (v<0) return 0; return v; } void fade_leds(int fd) { unsigned i; for (i = 0; i < N_LEDS; ++i) { current[i].r=f(current[i].r); current[i].g=f(current[i].g); current[i].b=f(current[i].b); } sync_leds(fd); } int open_kb (int *fds) { struct hidraw_devinfo info; unsigned i; int n = 0; for (i = 0; i < 128; ++i) { int fd; char device[128]; char buf[128]; sprintf (device, "/dev/hidraw%d", i); fd = open (device, O_RDWR | O_NONBLOCK); if (fd < 0) continue; memset (buf, 0, sizeof (buf)); ioctl (fd, HIDIOCGRAWNAME (256), buf); buf[sizeof (buf) - 1] = 0; if (strcmp (buf, "YMDK YMD09_32A")) { close (fd); fd = -1; continue; } fds[n++] = fd; } if (n < 2) { printf ("Devices not found\n"); return -1; } return 0; } int main (int argc, char **argv) { int fds[2]; fd_set rfds; ssize_t len; char buf[32]; struct timeval tv; unsigned j, k; memset (last, 0xff, sizeof (last)); if (open_kb (fds)) return -1; current[4].g=0xff; FD_ZERO (&rfds); sync_leds (fds[1]); tv.tv_sec=0; tv.tv_usec=0; for (;;) { FD_SET (fds[0], &rfds); if (!tv.tv_usec) tv.tv_usec=20000; switch (select (fds[0] + 1, &rfds, NULL, NULL, &tv)) { case -1: break; case 1: len = read (fds[0], buf, sizeof (buf)); if (len < 3) break; for (j = 2; j < len; ++j) { if (!buf[j]) continue; k = buf[j] - 4; current[k].r = rand() & 0xff ; current[k].g = rand() & 0xff ; current[k].b = rand() & 0xff ; } sync_leds (fds[1]); break; case 0: fade_leds(fds[1]); } } close (fds[1]); close (fds[0]); return 0; }