Dulcimer/firmware/commandhandler.c

188 lines
6.2 KiB
C
Raw Normal View History

/**
* \file commandhandler.c
* \brief TODO
* \author Ronald Schaten <ronald@schatenseite.de>
* \version $Id$
*
* License: TODO
*/
#include "commandhandler.h"
#include "keycodes.h"
#include "tools.h"
#include "modelinterface.h"
// TODO comment
typedef enum {
standard,
commandmode,
macrocommand,
macrodefinition,
macrodelete,
complexcommand
} Commandstate;
static Commandstate commandstate = standard;
#define MACROCOUNT 10
#define MACROLENGTH 20
// macrodefinitions[][0] is the macro-key
Key macrodefinitions[MACROCOUNT][MACROLENGTH + 1];
uint8_t macrocountindex = 0;
uint8_t macrodefinitionindex = 0;
uint8_t getMacroindex(Key macrokey) {
for (uint8_t i = 0; i < MACROCOUNT; i++) {
if ((macrodefinitions[i][0].mode == macrokey.mode) && (macrodefinitions[i][0].key == macrokey.key)) {
return i;
}
}
return MACROCOUNT;
}
void deleteMacroindex(Key macrokey) {
for (uint8_t i = 0; i < MACROCOUNT; i++) {
if ((macrodefinitions[i][0].mode == macrokey.mode) && (macrodefinitions[i][0].key == macrokey.key)) {
macrodefinitions[i][0].mode = MOD_NONE;
macrodefinitions[i][0].key = KEY_Reserved;
break;
}
}
}
void sendMacro(uint8_t index) {
for (uint8_t i = 0; i < MACROLENGTH; i++) {
if(macrodefinitions[index][i+1].key != KEY_Reserved) {
sendKey(macrodefinitions[index][i+1]);
} else {
break;
}
}
}
uint8_t checkmacrodefinition(uint8_t* reportbuffer) {
if ((reportbuffer[2] != KEY_Reserved) && (reportbuffer[3] == KEY_Reserved)) {
Key macrokey;
macrokey.mode = reportbuffer[0];
macrokey.key = reportbuffer[2];
return getMacroindex(macrokey);
}
return MACROCOUNT;
}
uint8_t setMacroindex(Key macrokey) {
for (uint8_t i = 0; i < MACROCOUNT; i++) {
if ((macrodefinitions[i][0].mode == macrokey.mode) && (macrodefinitions[i][0].key == macrokey.key)) {
macrodefinitions[i][0].mode = MOD_NONE;
macrodefinitions[i][0].key = KEY_Reserved;
break;
}
}
for (uint8_t i = 0; i < MACROCOUNT; i++) {
if ((macrodefinitions[i][0].mode == MOD_NONE) && (macrodefinitions[i][0].key == KEY_Reserved)) {
macrodefinitions[i][0].mode = macrokey.mode;
macrodefinitions[i][0].key = macrokey.key;
return i;
}
}
return MACROCOUNT;
}
uint8_t iskey(uint8_t* reportbuffer, uint8_t modifier, uint8_t key) {
if ((reportbuffer[0] == modifier) && (reportbuffer[2] == key) && (reportbuffer[3] == KEY_Reserved)) {
return 1;
} else {
return 0;
}
}
uint8_t ishotkey(uint8_t* reportbuffer) {
return iskey(reportbuffer, (MOD_SHIFT_LEFT | MOD_SHIFT_RIGHT), KEY_D);
}
void keypressed(uint8_t* reportbuffer, uint8_t size, uint16_t tickcounter) {
switch (commandstate) {
case commandmode:
if (iskey(reportbuffer, (MOD_SHIFT_LEFT | MOD_SHIFT_RIGHT), KEY_Reserved) ||
iskey(reportbuffer, MOD_SHIFT_LEFT, KEY_Reserved) ||
iskey(reportbuffer, MOD_SHIFT_RIGHT, KEY_Reserved) ||
iskey(reportbuffer, MOD_NONE, KEY_Reserved)) {
// ignore pressed shift-keys, probably still pressed from hot
// key usage
} else if (iskey(reportbuffer, MOD_NONE, KEY_T)) {
// toggle function
toggle();
commandstate = standard;
} else if (iskey(reportbuffer, MOD_NONE, KEY_M)) {
// record macro
commandstate = macrocommand;
} else if (iskey(reportbuffer, MOD_SHIFT_LEFT, KEY_M) || iskey(reportbuffer, MOD_SHIFT_RIGHT, KEY_M)) {
// delete macro
commandstate = macrodelete;
} else {
// command not recognized, return to standard mode
commandstate = standard;
}
break;
case macrocommand:
if (reportbuffer[2] == KEY_Reserved) {
// just modifier pressed => ignore
} else {
Key macrokey;
macrokey.mode = reportbuffer[0];
macrokey.key = reportbuffer[2];
macrocountindex = setMacroindex(macrokey);
if (macrocountindex == MACROCOUNT) {
// no space left
commandstate = standard;
} else {
commandstate = macrodefinition;
macrodefinitionindex = 0;
}
}
break;
case macrodefinition:
if (ishotkey(reportbuffer)) {
// macro definition complete
macrodefinitions[macrocountindex][macrodefinitionindex + 1].mode = MOD_NONE;
macrodefinitions[macrocountindex][macrodefinitionindex + 1].key = KEY_Reserved;
commandstate = standard;
} else if (reportbuffer[2] == KEY_Reserved) {
// just modifier pressed => ignore
} else {
macrodefinitions[macrocountindex][macrodefinitionindex + 1].mode = reportbuffer[0];
macrodefinitions[macrocountindex][macrodefinitionindex + 1].key = reportbuffer[2];
macrodefinitionindex++;
if (macrodefinitionindex == MACROLENGTH) {
// no space left in this macro
commandstate = standard;
}
}
break;
case macrodelete:
if (reportbuffer[2] == KEY_Reserved) {
// just modifier pressed => ignore
} else {
Key macrokey;
macrokey.mode = reportbuffer[0];
macrokey.key = reportbuffer[2];
deleteMacroindex(macrokey);
commandstate = standard;
}
break;
case complexcommand:
break;
default:
if (ishotkey(reportbuffer)) {
commandstate = commandmode;
} else if ((macrocountindex = checkmacrodefinition(reportbuffer)) != MACROCOUNT) {
sendMacro(macrocountindex);
} else {
usbSendReportBuffer(reportbuffer, size);
}
}
}