14. Griffin Hardware
The griffin knob is a secondary core peripharal used in Monolith that is used alongside the Monome. It is controlled using the hidapi wrapper.
14.1. hidapi system include
The hidapi uses a system include hidapi/hidapi.h
#ifndef MONOLITH_SIMPLE
#include "hidapi/hidapi.h"
#endif14.2. Griffin Hardware Data
Griffin is stored in an hidapi handle of type hid_devicecalled griffin_handle.
#ifndef MONOLITH_SIMPLE
hid_device *griffin_handle;
#endif#ifndef MONOLITH_SIMPLE
m->griffin_handle = NULL;
#endifIt is closed with hid_close.
#ifndef MONOLITH_SIMPLE
if(m->griffin_handle != NULL) hid_close(m->griffin_handle);
#endif14.3. Griffin Setup and Cleanup
The Griffin knob is started and initialized with the
function monolith_griffin_setup.
void monolith_griffin_setup(monolith_d *m);The nice thing about the hidapi wrapper is that is loads devices using Vendor and Product ID numbers, which are cross-platform. No os-dependent code needed with this layer, which is nice.
We want pulling to be non-blocking, so this must be
explicitely set using hid_set_nonblocking.
void monolith_griffin_setup(monolith_d *m)
{
#ifndef MONOLITH_SIMPLE
    monolith_griffin_d *g;
    g = &m->vgriffin;
    if(m->griffin_handle != NULL) return;
    m->griffin_handle = hid_open(0x077d, 0x0410, NULL);
    if(m->griffin_handle == NULL) {
        fprintf(stderr, "Could not open Griffin knob\n");
        return;
    }
    hid_set_nonblocking(m->griffin_handle, 1);
<<set_griffin_callbacks>>
#endif
}Griffin setup is implemented as a function called
monolith:griffin-setup.
{"monolith:griffin-setup", pp_griffin_setup, 0, 0, {CHR,___,___}},static cell pp_griffin_setup(cell x) {
    monolith_griffin_setup(monolith_data_get());
    return UNSPECIFIC;
}At the end of the program, the griffin is closed with the
function monolith_griffin_cleanup.
void monolith_griffin_cleanup(monolith_d *m);void monolith_griffin_cleanup(monolith_d *m)
{
<<close_griffin_handle>>
}This gets called at cleanup.
monolith_griffin_cleanup(m);14.4. Polling the Griffin
Griffin events are pulled with the function
monolith_griffin_poll.
This is code directly lifted from monomer.
void monolith_griffin_poll(monolith_d *m);void monolith_griffin_poll(monolith_d *m)
{
#ifndef MONOLITH_SIMPLE
    static unsigned char buf[16];
    int res;
    if(m->griffin_handle == NULL) return;
    res = hid_read(m->griffin_handle, buf, 16);
    if(res > 0) {
        if(buf[1] == 0) {
            monolith_griffin_push(&m->vgriffin, buf[0]);
        } else if(buf[1] > 0) {
            monolith_griffin_turn(&m->vgriffin,
                                  (signed char)buf[1]);
        }
    }
#endif
}The poll function is called inside of the main poll callback.
#ifndef MONOLITH_SIMPLE
monolith_griffin_poll(m);
#endif14.5. Set Griffin Callbacks
14.5.1. Set Default Turn Callback
#ifndef MONOLITH_SIMPLE
static void griffin_turn(monolith_griffin_d *g, int state);
#endif#ifndef MONOLITH_SIMPLE
static void griffin_turn(monolith_griffin_d *g, int state)
{
    if(g->md->curpage != NULL) {
        monolith_page_turn(g->md->curpage, state);
    }
}
#endifmonolith_griffin_turn_set(g, griffin_turn);14.5.2. Set Default Push Callback
#ifndef MONOLITH_SIMPLE
static void griffin_push(monolith_griffin_d *g, int state);
#endif#ifndef MONOLITH_SIMPLE
static void griffin_push(monolith_griffin_d *g, int state)
{
    if(g->md->curpage != NULL) {
        monolith_page_push(g->md->curpage, state);
    }
}
#endifmonolith_griffin_push_set(g, griffin_push);prev | home | next