Input Test
In this tutorial, you’ll make a small input viewer. It waits for events and prints what happened on the screen.
This is useful when you want to learn which keys and touch events the calculator sends to your app.
You will learn how to:
- Wait for input with
GetInput - Detect key, touch, and action bar events
- Print debug text to the LCD
- Quit with
Clear
Step 1: Include the SDK headers
Section titled “Step 1: Include the SDK headers”The demo uses debug printing, input events, LCD refresh, and memory clearing:
#include <appdef.h>#include <sdk/os/debug.h>#include <sdk/os/input.h>#include <sdk/os/lcd.h>#include <sdk/os/mem.h>debug.h is used for text. input.h is used for the event structure. lcd.h is used to clear and refresh the screen.
Step 2: Add app metadata
Section titled “Step 2: Add app metadata”Put this after the includes:
APP_NAME("Input Test")APP_DESCRIPTION("Test of the GetInput function.")APP_AUTHOR("The6P4C")APP_VERSION("1.0.0")Step 3: Create a key lookup entry
Section titled “Step 3: Create a key lookup entry”The calculator gives key codes as numbers. For a tutorial, numbers are hard to read, so the demo maps key codes to names:
struct LUTEntry { const char *str; uint32_t keyCode;};One entry contains the text to print and the key code to compare against.
Step 4: Build the key lookup table
Section titled “Step 4: Build the key lookup table”The final demo has one entry for each common key:
struct LUTEntry lut[] = { {"KEYBOARD", 0x00B3}, {"SHIFT", 0x00A0}, {"BACKSPACE", 0x0097}, {"POWER_CLEAR", 0x0080}, {"UP", 0x0090}, {"DOWN", 0x0091}, {"LEFT", 0x0092}, {"RIGHT", 0x0093}, {"EXE", 0x0094}};The real table in the final code is longer, but it works the same way. Your own app can also compare directly with constants like KEYCODE_UP.
Step 5: Print a header
Section titled “Step 5: Print a header”This helper function prints the title at the top:
void printHeader() { Debug_SetCursorPosition(0, 0); Debug_PrintString("GetInput demo (clear=quit)", false);}Debug text goes into the screen buffer. You still need LCD_Refresh() to show it.
Step 6: Create the main loop
Section titled “Step 6: Create the main loop”Start main() by clearing the screen and printing the header:
int main() { struct Input_Event event;
bool running = true;
LCD_ClearScreen(); printHeader(); LCD_Refresh();
while (running) { // read events here }
return 0;}Step 7: Wait for input
Section titled “Step 7: Wait for input”Inside the loop, clear the event structure and wait for the next event:
Mem_Memset(&event, 0, sizeof(event));GetInput(&event, 0xFFFFFFFF, 0x10);GetInput() blocks until something happens, then stores the result in event.
Step 8: Handle key events
Section titled “Step 8: Handle key events”Start with the key event case:
case EVENT_KEY: LCD_ClearScreen(); printHeader();
Debug_SetCursorPosition(0, 1); Debug_PrintString("Key Event", true);Then print the key direction:
Debug_SetCursorPosition(0, 3);Debug_PrintString("Direction: ", false);
switch (event.data.key.direction) {case KEY_PRESSED: Debug_PrintString("pressed", false); break;case KEY_HELD: Debug_PrintString("held", false); break;case KEY_RELEASED: Debug_PrintString("released", false); break;}Finally, search the lookup table and print the key name.
Step 9: Handle touch events
Section titled “Step 9: Handle touch events”Touch events use a different part of the event structure:
case EVENT_TOUCH: LCD_ClearScreen(); printHeader();
Debug_SetCursorPosition(0, 1); Debug_PrintString("Touch Event", true);
Debug_SetCursorPosition(0, 4); Debug_PrintString("x:", false); Debug_PrintNumberHex_Dword(event.data.touch_single.p1_x, 3, 4);
Debug_SetCursorPosition(0, 5); Debug_PrintString("y:", false); Debug_PrintNumberHex_Dword(event.data.touch_single.p1_y, 3, 5);
LCD_Refresh(); break;The final code also prints whether the touch is down, up, held, or from the action bar.
Step 10: Exit with Clear
Section titled “Step 10: Exit with Clear”When the key code is KEYCODE_POWER_CLEAR, the loop stops:
if (event.data.key.keyCode == KEYCODE_POWER_CLEAR) { running = false;}At this point, the input viewer is complete. The final code below includes the full key table and all event cases.
Final Code
Section titled “Final Code”#include <appdef.h>#include <sdk/os/debug.h>#include <sdk/os/input.h>#include <sdk/os/lcd.h>#include <sdk/os/mem.h>
APP_NAME("Input Test")APP_DESCRIPTION("Test of the GetInput function.")APP_AUTHOR("The6P4C")APP_VERSION("1.0.0")
struct LUTEntry { const char *str; uint32_t keyCode;};
struct LUTEntry lut[] = { {"KEYBOARD", 0x00B3}, {"SHIFT", 0x00A0}, {"BACKSPACE", 0x0097}, {"POWER_CLEAR", 0x0080}, {"UP", 0x0090}, {"DOWN", 0x0091}, {"LEFT", 0x0092}, {"RIGHT", 0x0093}, {"EQUALS", 0x003D}, {"X", 0xEDB8}, {"Y", 0xEDB9}, {"Z", 0xEDBA}, {"POWER", 0x005E}, {"DIVIDE", 0x002F}, {"OPEN_PARENTHESIS", 0x0028}, {"7", 0x0037}, {"8", 0x0038}, {"9", 0x0039}, {"TIMES", 0xEE10}, {"CLOSE_PARENTHESIS", 0x0029}, {"4", 0x0034}, {"5", 0x0035}, {"6", 0x0036}, {"MINUS", 0x002D}, {"COMMA", 0x002C}, {"1", 0x0031}, {"2", 0x0032}, {"3", 0x0033}, {"PLUS", 0x002B}, {"NEGATIVE", 0x001F}, {"0", 0x0030}, {"DOT", 0x002E}, {"EXP", 0x001D}, {"EXE", 0x0094}};
void printHeader() { Debug_SetCursorPosition(0, 0); Debug_PrintString("GetInput demo (clear=quit)", false);}
int main() { struct Input_Event event;
bool running = true;
LCD_ClearScreen(); printHeader(); LCD_Refresh();
while (running) { Mem_Memset(&event, 0, sizeof(event)); GetInput(&event, 0xFFFFFFFF, 0x10);
switch (event.type) { case EVENT_KEY: LCD_ClearScreen();
printHeader();
Debug_SetCursorPosition(0, 1); Debug_PrintString("Key Event", true);
Debug_SetCursorPosition(0, 3); Debug_PrintString("Direction: ", false);
switch (event.data.key.direction) { case KEY_PRESSED: Debug_PrintString("pressed", false); break; case KEY_HELD: Debug_PrintString("held", false); break; case KEY_RELEASED: Debug_PrintString("released", false); break; }
Debug_SetCursorPosition(0, 4); Debug_PrintString("Key code: ", false);
// Wrap in a block to avoid "jump to case label" errors due to the // definition of the variable i { int i = 0; while (true) { struct LUTEntry lutEntry = lut[i++];
if (event.data.key.keyCode == lutEntry.keyCode) { Debug_PrintString(lutEntry.str, false); break; } } }
LCD_Refresh();
if (event.data.key.keyCode == KEYCODE_POWER_CLEAR) { running = false; } break; case EVENT_TOUCH: LCD_ClearScreen();
printHeader();
Debug_SetCursorPosition(0, 1); Debug_PrintString("Touch Event", true);
Debug_SetCursorPosition(0, 3); Debug_PrintString("Direction: ", false);
switch (event.data.touch_single.direction) { case TOUCH_DOWN: Debug_PrintString("down", false); break; case TOUCH_HOLD_DRAG: Debug_PrintString("hold/drag", false); break; case TOUCH_ACT_BAR: Debug_PrintString("act. bar", false); break; case TOUCH_UP: Debug_PrintString("up", false); break; }
Debug_SetCursorPosition(0, 4); Debug_PrintString("x:", false); Debug_PrintNumberHex_Dword(event.data.touch_single.p1_x, 3, 4);
Debug_SetCursorPosition(0, 5); Debug_PrintString("y:", false); Debug_PrintNumberHex_Dword(event.data.touch_single.p1_y, 3, 5);
LCD_Refresh(); break; case EVENT_ACTBAR_RESIZE: case EVENT_ACTBAR_SWAP: case EVENT_ACTBAR_ROTATE: case EVENT_ACTBAR_ESC: case EVENT_ACTBAR_SETTINGS: LCD_ClearScreen();
printHeader();
Debug_SetCursorPosition(0, 1); Debug_PrintString("Act. Bar Event", true);
Debug_SetCursorPosition(0, 3); Debug_PrintString("Location: ", false);
switch (event.type) { case EVENT_ACTBAR_RESIZE: Debug_PrintString("Resize", false); break; case EVENT_ACTBAR_SWAP: Debug_PrintString("Swap", false); break; case EVENT_ACTBAR_ROTATE: Debug_PrintString("Rotate", false); break; case EVENT_ACTBAR_ESC: Debug_PrintString("Esc", false); break; case EVENT_ACTBAR_SETTINGS: Debug_PrintString("Settings", false); break; default: __builtin_unreachable(); }
LCD_Refresh(); break; default: break; } } return 0;}