Skip to content
Snippets Groups Projects
Select Git revision
21 results Searching

github.js

Blame
  • blink1raw.c 4.69 KiB
    /* 
     * blinkraw.c
     *
     * fgmr 2012-09-22
     *
     * playing with the hidraw interface to blink(1)
     * 
     * Thank you Alan Ott for
     * http://lxr.free-electrons.com/source/samples/hidraw/hid-example.c
     */
    
    #include <linux/types.h>
    #include <linux/input.h>
    #include <linux/hidraw.h>
    
    #ifndef HIDIOCSFEATURE
    #define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
    #define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
    #endif /* HIDIOCSFEATURE */
    
    #include <sys/ioctl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <stdarg.h>
    #include <ctype.h>
    
    static void
    usage(const char* hunh) {
      if (NULL != hunh) {
        fprintf(stderr, "Can't understand %s\n", hunh);
      }
    
      fprintf(stderr,
              "Usage: blinkraw {arg, ...}\n"
              "  /dev/whatever  -- open device\n"
              "  ./whatever     -- open device\n"
              "  =R,G,B,t       -- fade to color\n"
              "  :R,G,B         -- set color (now)\n"
              "  @step:R,G,B,t  -- set step\n"
              "  +step          -- start playing at step\n"
              "  -[step]        -- stop playing at step (default zero)\n"
              "  %%              -- clear all steps\n"
              "  _              -- turn off\n"
              "  _t             -- fade off\n"
              "\n"
              "       step is on [0,15]\n",
              "       R, G, B are on [0, 255]\n"
              "       t is time in centiseconds\n"
              "\n"
              "    Arguments are applied in order.  A new device, which is\n"
              "    a valid blink(1) device, will become the new target.\n"
              "\n"
              "    Example:\n"
              "    # blinkraw /dev/hidraw* % =255,0,0,100\n"
              );
      exit(1);
    }
    
    static void
    color(int fd, char action, int R, int G, int B, int T, int step) {
      char buf[16];
      int rc;
    
      if (-1 == fd) return;
    
      memset(buf, 0, sizeof(buf));
    
      if (R<0) R=0;
      if (G<0) G=0;
      if (B<0) B=0;
      if (T<0) T=0;
      if (step<0) step=0;
    
      if (R>255) R=255;
      if (G>255) G=255;
      if (B>255) B=255;
      if (T>65535) T=65535;
      if (step>15) step=15;
      
      buf[0] = 1;
      buf[1] = action;
      buf[2] = R; /* R */
      buf[3] = G; /* G */
      buf[4] = B; /* B */
      buf[5] = (T >>8);    /* time/cs high */
      buf[6] = (T & 0xff); /* time/cs low */
      buf[7] = step;
      buf[8] = 0;
    
      rc = ioctl(fd, HIDIOCSFEATURE(9), buf);
      if (rc < 0) perror("HIDIOCSFEATURE");
    }
    
    static void
    play(int fd, char action, int play, int step) {
      char buf[16];
      int rc;
    
      if (-1 == fd) return;
    
      memset(buf, 0, sizeof(buf));
    
      buf[0] = 1;
      buf[1] = action;
      buf[2] = play;
      buf[3] = step;
    
      rc = ioctl(fd, HIDIOCSFEATURE(9), buf);
      if (rc < 0) perror("HIDIOCSFEATURE");
    }
    
    static int
    isblink1(int fd) {
      int rc;
      struct hidraw_devinfo info;
      memset(&info, 0, sizeof(info));
    
      rc = ioctl(fd, HIDIOCGRAWINFO, &info);
      if (rc < 0) {
        perror("HIDIOCGRAWINFO");
        return 0;
      }
    
      if ((info.vendor == 0x27b8) && (info.product == 0x01ed)) {
        return 1;
      } else {
        return 0;
      }
    }
    
    int
    main(int argc, char *argv[]) {
      int fd = -1;
    
      if (argc < 2) usage(NULL);
    
      while(++argv, --argc) {
        int rc = -1;
        int step = 0;
        int R = 0;
        int G = 0;
        int B = 0;
        int T = 0;
        char buf[16];
    
        memset(buf, 0, sizeof(buf));
    
        switch(**argv) {
        case '/': case '.':
          rc = open(*argv, O_RDWR|O_NONBLOCK);
          if (rc < 0) {
            perror(*argv);
            continue;
          }
    
          if (isblink1(rc)) {
            if (fd >= 0) close(fd);
            fd = rc;
          }
    
          break;
        case '=':
          rc = sscanf(*argv, "=%d,%d,%d,%d", &R, &G, &B, &T);
          if (rc != 4) usage(*argv);
          color(fd, 'c', R, G, B, T, 0);
          break;
        case ':':
          rc = sscanf(*argv, ":%d,%d,%d", &R, &G, &B);
          if (rc != 3) usage(*argv);
          color(fd, 'n', R, G, B, 0, 0);
          break;
        case '@':
          rc = sscanf(*argv, "@%d:%d,%d,%d,%d", &step, &R, &G, &B, &T);
          if (rc != 5) usage(*argv);
          if ((step < 0) || step > 15) usage(*argv);
          color(fd, 'P', R, G, B, T, step);
          break;
        case '_':
          rc = sscanf(*argv, "_%d", &T);
          if (rc == 1) color(fd, 'c', 0, 0, 0, T, 0);
          else color(fd, 'n', 0, 0, 0, 0, 0);
          break;
        case '+':
          rc = sscanf(*argv, "+%d", &step);
          if (rc != 1) usage(*argv);
          if ((step < 0) || step > 15) usage(*argv);
          play(fd, 'p', 1, step);
          break;
        case '-':
          rc = sscanf(*argv, "-%d", &step);
          if (rc != 1) step = 0;
          if ((step < 0) || step > 15) step = 0;
          play(fd, 'p', 0, step);
          break;
        case '%':
          for(step = 0; step < 16; ++step) {
            color(fd, 'P', 0, 0, 0, 0, step);
          }
          break;
        default:
          usage(*argv);
        }
      }
    
      close(fd);
      return 0;
    }