]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Macro/PartialMap/macro.c
Initial work for KLL macro support
[kiibohd-controller.git] / Macro / PartialMap / macro.c
1 /* Copyright (C) 2014 by Jacob Alexander
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21
22 // ----- Includes -----
23
24 // Compiler Includes
25 #include <Lib/MacroLib.h>
26
27 // Project Includes
28 #include <cli.h>
29 #include <led.h>
30 #include <print.h>
31 #include <scan_loop.h>
32 #include <output_com.h>
33
34 // Keymaps
35 #include "usb_hid.h"
36 #include <defaultMap.h>
37
38 // Local Includes
39 #include "macro.h"
40
41
42
43 // ----- Function Declarations -----
44
45 void cliFunc_capList    ( char* args );
46 void cliFunc_capSelect  ( char* args );
47 void cliFunc_lookComb   ( char* args );
48 void cliFunc_lookDefault( char* args );
49 void cliFunc_lookPartial( char* args );
50 void cliFunc_macroDebug ( char* args );
51
52
53
54 // ----- Variables -----
55
56 // Macro Module command dictionary
57 char*       macroCLIDictName = "Macro Module Commands (Not all commands fully work yet...)";
58 CLIDictItem macroCLIDict[] = {
59         { "capList",     "Prints an indexed list of all non USB keycode capabilities.", cliFunc_capList },
60         { "capSelect",   "Triggers the specified capability." NL "\t\t\033[35mU10\033[0m USB Code 0x0A, \033[35mK11\033[0m Keyboard Capability 0x0B, \033[35mS12\033[0m Scancode 0x0C", cliFunc_capSelect },
61         { "lookComb",    "Do a lookup on the Combined map." NL "\t\t\033[35mS10\033[0m Scancode 0x0A, \033[35mU11\033[0m USB Code 0x0B", cliFunc_lookComb },
62         { "lookDefault", "Do a lookup on the Default map." NL "\t\t\033[35mS10\033[0m Scancode 0x0A", cliFunc_lookDefault },
63         { "lookPartial", "Do a lookup on the layered Partial maps." NL "\t\t\033[35mS10\033[0m Scancode 0x0A, \033[35mU11\033[0m USB Code 0x0B", cliFunc_lookPartial },
64         { "macroDebug",  "Disables/Enables sending USB keycodes to the Output Module and prints U/K codes.", cliFunc_macroDebug },
65         { 0, 0, 0 } // Null entry for dictionary end
66 };
67
68
69 // Macro debug flag - If set, clears the USB Buffers after signalling processing completion
70 uint8_t macroDebugMode = 0;
71
72
73
74 // ----- Functions -----
75
76 // Looks up the start of the function ptr list for the active layer, by scan code
77 inline void *Macro_layerLookup( uint8_t scanCode )
78 {
79         // TODO
80         return 0;
81 }
82
83
84 // Called for each key from the Scan Module for one of three cases:
85 //  1. Key is pressed         (PRESSED)
86 //  2. Key is being held down (HELD)
87 //  3. Key is released        (RELEASED)
88 // If Scan Module is for an analog sense keyboard, do not use the defined keystates
89 // This function should not be called if not pressed (depressed) or at 0%
90 inline void Macro_keyUpdate( uint8_t scanCode, uint8_t state )
91 {
92         // Do layer lookup to find which capabilities to map
93         void *capabilities = Macro_layerLookup( scanCode );
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 inline void Macro_bufferAdd( uint8_t byte )
115 {
116         // Make sure we haven't overflowed the key buffer
117         // Default function for adding keys to the KeyIndex_Buffer, does a DefaultMap_Lookup
118         if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER )
119         {
120                 uint8_t key = DefaultMap_Lookup[byte];
121                 for ( uint8_t c = 0; c < KeyIndex_BufferUsed; c++ )
122                 {
123                         // Key already in the buffer
124                         if ( KeyIndex_Buffer[c] == key )
125                                 return;
126                 }
127
128                 // Add to the buffer
129                 KeyIndex_Buffer[KeyIndex_BufferUsed++] = key;
130         }
131 }
132
133 inline void Macro_bufferRemove( uint8_t byte )
134 {
135         uint8_t key = DefaultMap_Lookup[byte];
136
137         // Check for the released key, and shift the other keys lower on the buffer
138         for ( uint8_t c = 0; c < KeyIndex_BufferUsed; c++ )
139         {
140                 // Key to release found
141                 if ( KeyIndex_Buffer[c] == key )
142                 {
143                         // Shift keys from c position
144                         for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
145                                 KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
146
147                         // Decrement Buffer
148                         KeyIndex_BufferUsed--;
149
150                         return;
151                 }
152         }
153
154         // Error case (no key to release)
155         erro_msg("Could not find key to release: ");
156         printHex( key );
157 }
158
159 inline void Macro_finishWithUSBBuffer( uint8_t sentKeys )
160 {
161 }
162
163 inline void Macro_process()
164 {
165         // Only do one round of macro processing between Output Module timer sends
166         if ( USBKeys_Sent != 0 )
167                 return;
168
169         // Loop through input buffer
170         for ( uint8_t index = 0; index < KeyIndex_BufferUsed && !macroDebugMode; index++ )
171         {
172                 //print(" KEYS: ");
173                 //printInt8( KeyIndex_BufferUsed );
174                 // Get the keycode from the buffer
175                 uint8_t key = KeyIndex_Buffer[index];
176
177                 // Set the modifier bit if this key is a modifier
178                 if ( (key & KEY_LCTRL) == KEY_LCTRL ) // AND with 0xE0
179                 {
180                         USBKeys_Modifiers |= 1 << (key ^ KEY_LCTRL); // Left shift 1 by key XOR 0xE0
181
182                         // Modifier processed, move on to the next key
183                         continue;
184                 }
185
186                 // Too many keys
187                 if ( USBKeys_Sent >= USBKeys_MaxSize )
188                 {
189                         warn_msg("USB Key limit reached");
190                         errorLED( 1 );
191                         break;
192                 }
193
194                 // Allow ignoring keys with 0's
195                 if ( key != 0 )
196                 {
197                         USBKeys_Array[USBKeys_Sent++] = key;
198                 }
199                 else
200                 {
201                         // Key was not mapped
202                         erro_msg( "Key not mapped... - " );
203                         printHex( key );
204                         errorLED( 1 );
205                 }
206         }
207
208         // Signal buffer that we've used it
209         Scan_finishedWithBuffer( KeyIndex_BufferUsed );
210
211         // If Macro debug mode is set, clear the USB Buffer
212         if ( macroDebugMode )
213         {
214                 USBKeys_Modifiers = 0;
215                 USBKeys_Sent = 0;
216         }
217 }
218
219 inline void Macro_setup()
220 {
221         // Register Macro CLI dictionary
222         CLI_registerDictionary( macroCLIDict, macroCLIDictName );
223
224         // Disable Macro debug mode
225         macroDebugMode = 0;
226 }
227
228
229 // ----- CLI Command Functions -----
230
231 void cliFunc_capList( char* args )
232 {
233         // TODO
234 }
235
236 void cliFunc_capSelect( char* args )
237 {
238         // Parse code from argument
239         //  NOTE: Only first argument is used
240         char* arg1Ptr;
241         char* arg2Ptr;
242         CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
243
244         // Depending on the first character, the lookup changes
245         switch ( arg1Ptr[0] )
246         {
247         // Keyboard Capability
248         case 'K':
249                 // TODO
250                 break;
251
252         // Scancode
253         case 'S':
254                 // Add to the USB Buffer using the DefaultMap lookup
255                 Macro_bufferAdd( decToInt( &arg1Ptr[1] ) );
256                 break;
257
258         // USB Code
259         case 'U':
260                 // Just add the key to the USB Buffer
261                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER )
262                 {
263                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = decToInt( &arg1Ptr[1] );
264                 }
265                 break;
266         }
267 }
268
269 void cliFunc_lookComb( char* args )
270 {
271         // Parse code from argument
272         //  NOTE: Only first argument is used
273         char* arg1Ptr;
274         char* arg2Ptr;
275         CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
276
277         // Depending on the first character, the lookup changes
278         switch ( arg1Ptr[0] )
279         {
280         // Scancode
281         case 'S':
282                 // TODO
283                 break;
284
285         // USB Code
286         case 'U':
287                 // TODO
288                 break;
289         }
290 }
291
292 void cliFunc_lookDefault( char* args )
293 {
294         // Parse code from argument
295         //  NOTE: Only first argument is used
296         char* arg1Ptr;
297         char* arg2Ptr;
298         CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
299
300         // Depending on the first character, the lookup changes
301         switch ( arg1Ptr[0] )
302         {
303         // Scancode
304         case 'S':
305                 print( NL );
306                 printInt8( DefaultMap_Lookup[decToInt( &arg1Ptr[1] )] );
307                 print(" ");
308                 printHex( DefaultMap_Lookup[decToInt( &arg1Ptr[1] )] );
309                 break;
310         }
311 }
312
313 void cliFunc_lookPartial( char* args )
314 {
315         // Parse code from argument
316         //  NOTE: Only first argument is used
317         char* arg1Ptr;
318         char* arg2Ptr;
319         CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
320
321         // Depending on the first character, the lookup changes
322         switch ( arg1Ptr[0] )
323         {
324         // Scancode
325         case 'S':
326                 // TODO
327                 break;
328
329         // USB Code
330         case 'U':
331                 // TODO
332                 break;
333         }
334 }
335
336 void cliFunc_macroDebug( char* args )
337 {
338         // Toggle macro debug mode
339         macroDebugMode = macroDebugMode ? 0 : 1;
340
341         print( NL );
342         info_msg("Macro Debug Mode: ");
343         printInt8( macroDebugMode );
344 }
345