Skip to content
Permalink
7feb8fbff4
Go to file
 
 
Cannot retrieve contributors at this time
203 lines (169 sloc) 6.04 KB
#include <assert.h>
#include <pthread.h>
#include <search.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <monome.h>
#include "../args.h"
#include "../events.h"
#include "device.h"
#include "device_monome.h"
//------------------------
//-- static functions
static void dev_monome_handle_press(const monome_event_t *e, void *p);
static void dev_monome_handle_lift(const monome_event_t *e, void *p);
static void dev_monome_handle_encoder_delta(const monome_event_t *e, void *p);
static void dev_monome_handle_encoder_press(const monome_event_t *e, void *p);
static void dev_monome_handle_encoder_lift(const monome_event_t *e, void *p);
//-------------------------
//--- monome device class
// allocate and initialize a new device
int dev_monome_init(void *self) {
struct dev_monome *md = (struct dev_monome *)self;
struct dev_common *base = (struct dev_common *)self;
const char *name;
const char *serial;
monome_t *m;
m = monome_open(md->dev.path);
if (!m) {
fprintf(stderr, "error: couldn't open monome device at %s\n", md->dev.path);
return -1;
}
md->m = m;
memset(md->data, 0, sizeof(md->data));
memset(md->dirty, 0, sizeof(md->dirty));
if (monome_get_rows(md->m) == 0 && monome_get_cols(md->m) == 0) {
md->type = DEVICE_MONOME_TYPE_ARC;
} else {
md->type = DEVICE_MONOME_TYPE_GRID;
}
monome_register_handler(m, MONOME_BUTTON_DOWN, dev_monome_handle_press, md);
monome_register_handler(m, MONOME_BUTTON_UP, dev_monome_handle_lift, md);
monome_register_handler(m, MONOME_ENCODER_DELTA, dev_monome_handle_encoder_delta, md);
monome_register_handler(m, MONOME_ENCODER_KEY_DOWN, dev_monome_handle_encoder_press, md);
monome_register_handler(m, MONOME_ENCODER_KEY_UP, dev_monome_handle_encoder_lift, md);
// drop the name set by udev and use libmonome-provided name
free(base->name);
name = monome_get_friendly_name(m);
base->name = strdup(name);
serial = monome_get_serial(m);
base->serial = strdup(serial);
base->start = &dev_monome_start;
base->deinit = &dev_monome_deinit;
return 0;
}
// calculate quadrant number given x/y
static inline uint8_t dev_monome_quad_idx(uint8_t x, uint8_t y) {
return ( (y > 7) << 1 ) | (x > 7);
}
// calcalate offset into quad data given x/y
static inline uint8_t dev_monome_quad_offset(uint8_t x, uint8_t y) {
return ( (y & 7) * 8 ) + (x & 7);
}
// set grid rotation
void dev_monome_set_rotation(struct dev_monome *md, uint8_t rotation) {
monome_set_rotation(md->m, rotation);
}
// set a given LED value
void dev_monome_grid_set_led(struct dev_monome *md,
uint8_t x, uint8_t y, uint8_t val) {
uint8_t q = dev_monome_quad_idx(x, y);
md->data[q][dev_monome_quad_offset(x, y)] = val;
md->dirty[q] = true;
}
// set a given LED value
void dev_monome_arc_set_led(struct dev_monome *md,
uint8_t n, uint8_t x, uint8_t val) {
md->data[n & 3][x & 63] = val;
md->dirty[n & 3] = true;
}
// set all LEDs to value
void dev_monome_all_led(struct dev_monome *md, uint8_t val) {
for(uint8_t q = 0; q < 4; q++) {
for(uint8_t i = 0; i < 64; i++) {
md->data[q][i] = val;
}
md->dirty[q] = true;
}
}
// transmit all dirty quads
void dev_monome_refresh(struct dev_monome *md) {
static const int quad_xoff[4] = {0, 8, 0, 8};
static const int quad_yoff[4] = {0, 0, 8, 8};
if (md->m == NULL) {
return;
}
for (int quad = 0; quad < 4; quad++) {
if (md->dirty[quad]) {
if (md->type == DEVICE_MONOME_TYPE_ARC) {
monome_led_ring_map(md->m, quad, md->data[quad]);
} else {
monome_led_level_map(md->m,
quad_xoff[quad],
quad_yoff[quad],
md->data[quad]);
}
md->dirty[quad] = false;
}
}
}
//--------------------
//--- static functions
static inline void
grid_key_event(const monome_event_t *e, void *p, int state) {
struct dev_monome *md = (struct dev_monome *)p;
union event_data *ev = event_data_new(EVENT_GRID_KEY);
ev->grid_key.id = md->dev.id;
ev->grid_key.x = e->grid.x;
ev->grid_key.y = e->grid.y;
ev->grid_key.state = state;
event_post(ev);
}
void dev_monome_handle_press(const monome_event_t *e, void *p) {
grid_key_event(e, p, 1);
}
void dev_monome_handle_lift(const monome_event_t *e, void *p) {
grid_key_event(e, p, 0);
}
void dev_monome_handle_encoder_delta(const monome_event_t *e, void *p) {
struct dev_monome *md = (struct dev_monome *)p;
union event_data *ev = event_data_new(EVENT_ARC_ENCODER_DELTA);
ev->arc_encoder_delta.id = md->dev.id;
ev->arc_encoder_delta.number = e->encoder.number;
ev->arc_encoder_delta.delta = e->encoder.delta;
event_post(ev);
}
void dev_monome_handle_encoder_press(const monome_event_t *e, void *p) {
struct dev_monome *md = (struct dev_monome *)p;
union event_data *ev = event_data_new(EVENT_ARC_ENCODER_KEY);
ev->arc_encoder_key.id = md->dev.id;
ev->arc_encoder_key.number = e->encoder.number;
ev->arc_encoder_key.state = 1;
event_post(ev);
}
void dev_monome_handle_encoder_lift(const monome_event_t *e, void *p) {
struct dev_monome *md = (struct dev_monome *)p;
union event_data *ev = event_data_new(EVENT_ARC_ENCODER_KEY);
ev->arc_encoder_key.id = md->dev.id;
ev->arc_encoder_key.number = e->encoder.number;
ev->arc_encoder_key.state = 0;
event_post(ev);
}
int dev_monome_grid_rows(struct dev_monome *md) {
return monome_get_rows(md->m);
}
int dev_monome_grid_cols(struct dev_monome *md) {
return monome_get_cols(md->m);
}
void *dev_monome_start(void *md) {
monome_event_loop(((struct dev_monome *)md)->m);
return NULL;
}
void dev_monome_deinit(void *self) {
struct dev_monome *md = (struct dev_monome *)self;
monome_close(md->m); // libmonome frees the monome_t pointer
md->m = NULL;
}