/** * \file commandhandler.c * \brief TODO * \author Ronald Schaten * \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); } } }