188 lines
6.2 KiB
C
188 lines
6.2 KiB
C
/**
|
|
* \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);
|
|
}
|
|
}
|
|
}
|