mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-10 05:59:08 -07:00
New GUI/View ASCII input API
This commit is contained in:
@@ -55,6 +55,16 @@ void gui_input_events_callback(const void* value, void* ctx) {
|
||||
furi_thread_flags_set(gui->thread_id, GUI_THREAD_FLAG_INPUT);
|
||||
}
|
||||
|
||||
void gui_ascii_events_callback(const void* value, void* ctx) {
|
||||
furi_assert(value);
|
||||
furi_assert(ctx);
|
||||
|
||||
Gui* gui = ctx;
|
||||
|
||||
furi_message_queue_put(gui->ascii_queue, value, FuriWaitForever);
|
||||
furi_thread_flags_set(gui->thread_id, GUI_THREAD_FLAG_ASCII);
|
||||
}
|
||||
|
||||
// Only Fullscreen supports vertical display for now
|
||||
static bool gui_redraw_fs(Gui* gui) {
|
||||
canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal);
|
||||
@@ -375,6 +385,35 @@ static void gui_input(Gui* gui, InputEvent* input_event) {
|
||||
gui_unlock(gui);
|
||||
}
|
||||
|
||||
static void gui_ascii(Gui* gui, AsciiEvent* ascii_event) {
|
||||
furi_assert(gui);
|
||||
furi_assert(ascii_event);
|
||||
|
||||
gui_lock(gui);
|
||||
|
||||
do {
|
||||
if(gui->direct_draw) {
|
||||
break;
|
||||
}
|
||||
|
||||
ViewPort* view_port = NULL;
|
||||
|
||||
if(gui->lockdown) {
|
||||
view_port = gui_view_port_find_enabled(gui->layers[GuiLayerDesktop]);
|
||||
} else {
|
||||
view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]);
|
||||
if(!view_port) view_port = gui_view_port_find_enabled(gui->layers[GuiLayerWindow]);
|
||||
if(!view_port) view_port = gui_view_port_find_enabled(gui->layers[GuiLayerDesktop]);
|
||||
}
|
||||
|
||||
if(view_port) {
|
||||
view_port_ascii(view_port, ascii_event);
|
||||
}
|
||||
} while(false);
|
||||
|
||||
gui_unlock(gui);
|
||||
}
|
||||
|
||||
void gui_lock(Gui* gui) {
|
||||
furi_assert(gui);
|
||||
furi_check(furi_mutex_acquire(gui->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
@@ -598,9 +637,13 @@ Gui* gui_alloc() {
|
||||
// Input
|
||||
gui->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
|
||||
gui->input_events = furi_record_open(RECORD_INPUT_EVENTS);
|
||||
gui->ascii_queue = furi_message_queue_alloc(8, sizeof(AsciiEvent));
|
||||
gui->ascii_events = furi_record_open(RECORD_ASCII_EVENTS);
|
||||
|
||||
furi_check(gui->input_events);
|
||||
furi_pubsub_subscribe(gui->input_events, gui_input_events_callback, gui);
|
||||
furi_check(gui->ascii_events);
|
||||
furi_pubsub_subscribe(gui->ascii_events, gui_ascii_events_callback, gui);
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
gui_add_view_port(gui, storage->sd_gui.view_port, GuiLayerStatusBarLeft);
|
||||
@@ -626,6 +669,14 @@ int32_t gui_srv(void* p) {
|
||||
gui_input(gui, &input_event);
|
||||
}
|
||||
}
|
||||
// Process and dispatch ascii
|
||||
if(flags & GUI_THREAD_FLAG_ASCII) {
|
||||
// Process till queue become empty
|
||||
AsciiEvent ascii_event;
|
||||
while(furi_message_queue_get(gui->ascii_queue, &ascii_event, 0) == FuriStatusOk) {
|
||||
gui_ascii(gui, &ascii_event);
|
||||
}
|
||||
}
|
||||
// Process and dispatch draw call
|
||||
if(flags & GUI_THREAD_FLAG_DRAW) {
|
||||
// Clear flags that arrived on input step
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
|
||||
#define GUI_THREAD_FLAG_DRAW (1 << 0)
|
||||
#define GUI_THREAD_FLAG_INPUT (1 << 1)
|
||||
#define GUI_THREAD_FLAG_ALL (GUI_THREAD_FLAG_DRAW | GUI_THREAD_FLAG_INPUT)
|
||||
#define GUI_THREAD_FLAG_ASCII (1 << 2)
|
||||
#define GUI_THREAD_FLAG_ALL (GUI_THREAD_FLAG_DRAW | GUI_THREAD_FLAG_INPUT | GUI_THREAD_FLAG_ASCII)
|
||||
|
||||
ARRAY_DEF(ViewPortArray, ViewPort*, M_PTR_OPLIST);
|
||||
|
||||
@@ -75,6 +76,9 @@ struct Gui {
|
||||
ViewPort* ongoing_input_view_port;
|
||||
|
||||
uint16_t hide_statusbar_count;
|
||||
|
||||
FuriMessageQueue* ascii_queue;
|
||||
FuriPubSub* ascii_events;
|
||||
};
|
||||
|
||||
/** Find enabled ViewPort in ViewPortArray
|
||||
|
||||
@@ -27,6 +27,11 @@ void view_set_input_callback(View* view, ViewInputCallback callback) {
|
||||
view->input_callback = callback;
|
||||
}
|
||||
|
||||
void view_set_ascii_callback(View* view, ViewAsciiCallback callback) {
|
||||
furi_assert(view);
|
||||
view->ascii_callback = callback;
|
||||
}
|
||||
|
||||
void view_set_custom_callback(View* view, ViewCustomCallback callback) {
|
||||
furi_assert(view);
|
||||
view->custom_callback = callback;
|
||||
@@ -156,6 +161,15 @@ bool view_input(View* view, InputEvent* event) {
|
||||
}
|
||||
}
|
||||
|
||||
bool view_ascii(View* view, AsciiEvent* event) {
|
||||
furi_assert(view);
|
||||
if(view->ascii_callback) {
|
||||
return view->ascii_callback(event, view->context);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool view_custom(View* view, uint32_t event) {
|
||||
furi_assert(view);
|
||||
if(view->custom_callback) {
|
||||
|
||||
@@ -48,6 +48,14 @@ typedef void (*ViewDrawCallback)(Canvas* canvas, void* model);
|
||||
*/
|
||||
typedef bool (*ViewInputCallback)(InputEvent* event, void* context);
|
||||
|
||||
/** View Ascii callback
|
||||
* @param event, pointer to ascii event data
|
||||
* @param context, pointer to context
|
||||
* @return true if event handled, false if event ignored
|
||||
* @warning called from GUI thread
|
||||
*/
|
||||
typedef bool (*ViewAsciiCallback)(AsciiEvent* event, void* context);
|
||||
|
||||
/** View Custom callback
|
||||
* @param event, number of custom event
|
||||
* @param context, pointer to context
|
||||
@@ -122,6 +130,13 @@ void view_set_draw_callback(View* view, ViewDrawCallback callback);
|
||||
*/
|
||||
void view_set_input_callback(View* view, ViewInputCallback callback);
|
||||
|
||||
/** Set View Ascii callback
|
||||
*
|
||||
* @param view View instance
|
||||
* @param callback ascii callback
|
||||
*/
|
||||
void view_set_ascii_callback(View* view, ViewAsciiCallback callback);
|
||||
|
||||
/** Set View Custom callback
|
||||
*
|
||||
* @param view View instance
|
||||
|
||||
@@ -10,6 +10,8 @@ ViewDispatcher* view_dispatcher_alloc() {
|
||||
view_dispatcher->view_port, view_dispatcher_draw_callback, view_dispatcher);
|
||||
view_port_input_callback_set(
|
||||
view_dispatcher->view_port, view_dispatcher_input_callback, view_dispatcher);
|
||||
view_port_ascii_callback_set(
|
||||
view_dispatcher->view_port, view_dispatcher_ascii_callback, view_dispatcher);
|
||||
view_port_enabled_set(view_dispatcher->view_port, false);
|
||||
|
||||
ViewDict_init(view_dispatcher->views);
|
||||
@@ -89,6 +91,8 @@ void view_dispatcher_run(ViewDispatcher* view_dispatcher) {
|
||||
break;
|
||||
} else if(message.type == ViewDispatcherMessageTypeInput) {
|
||||
view_dispatcher_handle_input(view_dispatcher, &message.input);
|
||||
} else if(message.type == ViewDispatcherMessageTypeAscii) {
|
||||
view_dispatcher_handle_ascii(view_dispatcher, &message.ascii);
|
||||
} else if(message.type == ViewDispatcherMessageTypeCustomEvent) {
|
||||
view_dispatcher_handle_custom_event(view_dispatcher, message.custom_event);
|
||||
}
|
||||
@@ -233,6 +237,24 @@ void view_dispatcher_input_callback(InputEvent* event, void* context) {
|
||||
}
|
||||
}
|
||||
|
||||
bool view_dispatcher_ascii_callback(AsciiEvent* event, void* context) {
|
||||
// Due to queue we cannot know ahead of time if event is consumed
|
||||
// So instead ViewDispatcher tells ViewPort that all events are consumed
|
||||
// Then ViewDispatcher handles fallbacks the same way as ViewPort would have done
|
||||
ViewDispatcher* view_dispatcher = context;
|
||||
if(view_dispatcher->queue) {
|
||||
ViewDispatcherMessage message;
|
||||
message.type = ViewDispatcherMessageTypeAscii;
|
||||
message.ascii = *event;
|
||||
furi_check(
|
||||
furi_message_queue_put(view_dispatcher->queue, &message, FuriWaitForever) ==
|
||||
FuriStatusOk);
|
||||
} else {
|
||||
view_dispatcher_handle_ascii(view_dispatcher, event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* event) {
|
||||
// Check input complementarity
|
||||
uint8_t key_bit = (1 << event->key);
|
||||
@@ -290,6 +312,48 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e
|
||||
}
|
||||
}
|
||||
|
||||
void view_dispatcher_handle_ascii(ViewDispatcher* view_dispatcher, AsciiEvent* event) {
|
||||
// Deliver event
|
||||
if(view_dispatcher->current_view) {
|
||||
// Dispatch ascii to current view
|
||||
bool is_consumed = view_ascii(view_dispatcher->current_view, event);
|
||||
|
||||
// Navigate if ascii is not consumed
|
||||
if(!is_consumed) {
|
||||
InputKey fallback_key = InputKeyMAX;
|
||||
switch(event->value) {
|
||||
case AsciiValueBS: // Backspace
|
||||
case AsciiValueESC: // Escape
|
||||
fallback_key = InputKeyBack;
|
||||
break;
|
||||
case AsciiValueDC1: // Up
|
||||
case AsciiValueDC2: // Down
|
||||
case AsciiValueDC3: // Right
|
||||
case AsciiValueDC4: // Left
|
||||
fallback_key = InputKeyUp + (event->value - AsciiValueDC1);
|
||||
break;
|
||||
case AsciiValueCR: // Enter
|
||||
fallback_key = InputKeyOk;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(fallback_key != InputKeyMAX) {
|
||||
// Fallback to directional input, needs press-short-release complementarity
|
||||
InputEvent fallback_event = {
|
||||
.key = fallback_key,
|
||||
.type = InputTypePress,
|
||||
};
|
||||
view_dispatcher_handle_input(view_dispatcher, &fallback_event);
|
||||
fallback_event.type = InputTypeShort;
|
||||
view_dispatcher_handle_input(view_dispatcher, &fallback_event);
|
||||
fallback_event.type = InputTypeRelease;
|
||||
view_dispatcher_handle_input(view_dispatcher, &fallback_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void view_dispatcher_handle_tick_event(ViewDispatcher* view_dispatcher) {
|
||||
if(view_dispatcher->tick_event_callback) {
|
||||
view_dispatcher->tick_event_callback(view_dispatcher->event_context);
|
||||
|
||||
@@ -34,6 +34,7 @@ struct ViewDispatcher {
|
||||
|
||||
typedef enum {
|
||||
ViewDispatcherMessageTypeInput,
|
||||
ViewDispatcherMessageTypeAscii,
|
||||
ViewDispatcherMessageTypeCustomEvent,
|
||||
ViewDispatcherMessageTypeStop,
|
||||
} ViewDispatcherMessageType;
|
||||
@@ -42,6 +43,7 @@ typedef struct {
|
||||
ViewDispatcherMessageType type;
|
||||
union {
|
||||
InputEvent input;
|
||||
AsciiEvent ascii;
|
||||
uint32_t custom_event;
|
||||
};
|
||||
} ViewDispatcherMessage;
|
||||
@@ -52,9 +54,15 @@ void view_dispatcher_draw_callback(Canvas* canvas, void* context);
|
||||
/** ViewPort Input Callback */
|
||||
void view_dispatcher_input_callback(InputEvent* event, void* context);
|
||||
|
||||
/** ViewPort Ascii Callback */
|
||||
bool view_dispatcher_ascii_callback(AsciiEvent* event, void* context);
|
||||
|
||||
/** Input handler */
|
||||
void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* event);
|
||||
|
||||
/** Ascii handler */
|
||||
void view_dispatcher_handle_ascii(ViewDispatcher* view_dispatcher, AsciiEvent* event);
|
||||
|
||||
/** Tick handler */
|
||||
void view_dispatcher_handle_tick_event(ViewDispatcher* view_dispatcher);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ struct ViewHolder {
|
||||
|
||||
static void view_holder_draw_callback(Canvas* canvas, void* context);
|
||||
static void view_holder_input_callback(InputEvent* event, void* context);
|
||||
static bool view_holder_ascii_callback(AsciiEvent* event, void* context);
|
||||
|
||||
ViewHolder* view_holder_alloc() {
|
||||
ViewHolder* view_holder = malloc(sizeof(ViewHolder));
|
||||
@@ -26,6 +27,7 @@ ViewHolder* view_holder_alloc() {
|
||||
view_holder->view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_holder->view_port, view_holder_draw_callback, view_holder);
|
||||
view_port_input_callback_set(view_holder->view_port, view_holder_input_callback, view_holder);
|
||||
view_port_ascii_callback_set(view_holder->view_port, view_holder_ascii_callback, view_holder);
|
||||
view_port_enabled_set(view_holder->view_port, false);
|
||||
|
||||
return view_holder;
|
||||
@@ -156,3 +158,15 @@ static void view_holder_input_callback(InputEvent* event, void* context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool view_holder_ascii_callback(AsciiEvent* event, void* context) {
|
||||
ViewHolder* view_holder = context;
|
||||
|
||||
bool is_consumed = false;
|
||||
|
||||
if(view_holder->view) {
|
||||
is_consumed = view_ascii(view_holder->view, event);
|
||||
}
|
||||
|
||||
return is_consumed;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ struct View {
|
||||
|
||||
void* model;
|
||||
void* context;
|
||||
|
||||
ViewAsciiCallback ascii_callback;
|
||||
};
|
||||
|
||||
/** IconAnimation tie callback */
|
||||
@@ -43,6 +45,9 @@ void view_draw(View* view, Canvas* canvas);
|
||||
/** Input Callback for View dispatcher */
|
||||
bool view_input(View* view, InputEvent* event);
|
||||
|
||||
/** Ascii Callback for View dispatcher */
|
||||
bool view_ascii(View* view, AsciiEvent* event);
|
||||
|
||||
/** Custom Callback for View dispatcher */
|
||||
bool view_custom(View* view, uint32_t event);
|
||||
|
||||
|
||||
@@ -174,6 +174,17 @@ void view_port_input_callback_set(
|
||||
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
|
||||
}
|
||||
|
||||
void view_port_ascii_callback_set(
|
||||
ViewPort* view_port,
|
||||
ViewPortAsciiCallback callback,
|
||||
void* context) {
|
||||
furi_assert(view_port);
|
||||
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
view_port->ascii_callback = callback;
|
||||
view_port->ascii_callback_context = context;
|
||||
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
|
||||
}
|
||||
|
||||
void view_port_update(ViewPort* view_port) {
|
||||
furi_assert(view_port);
|
||||
|
||||
@@ -228,6 +239,53 @@ void view_port_input(ViewPort* view_port, InputEvent* event) {
|
||||
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
|
||||
}
|
||||
|
||||
void view_port_ascii(ViewPort* view_port, AsciiEvent* event) {
|
||||
furi_assert(view_port);
|
||||
furi_assert(event);
|
||||
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
furi_check(view_port->gui);
|
||||
|
||||
bool is_consumed = false;
|
||||
if(view_port->ascii_callback) {
|
||||
is_consumed = view_port->ascii_callback(event, view_port->ascii_callback_context);
|
||||
}
|
||||
|
||||
if(!is_consumed) {
|
||||
InputKey fallback_key = InputKeyMAX;
|
||||
switch(event->value) {
|
||||
case AsciiValueBS: // Backspace
|
||||
case AsciiValueESC: // Escape
|
||||
fallback_key = InputKeyBack;
|
||||
break;
|
||||
case AsciiValueDC1: // Up
|
||||
case AsciiValueDC2: // Down
|
||||
case AsciiValueDC3: // Right
|
||||
case AsciiValueDC4: // Left
|
||||
fallback_key = InputKeyUp + (event->value - AsciiValueDC1);
|
||||
break;
|
||||
case AsciiValueCR: // Enter
|
||||
fallback_key = InputKeyOk;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(fallback_key != InputKeyMAX) {
|
||||
// Fallback to directional input, needs press-short-release complementarity
|
||||
InputEvent fallback_event = {
|
||||
.key = fallback_key,
|
||||
.type = InputTypePress,
|
||||
};
|
||||
view_port_input(view_port, &fallback_event);
|
||||
fallback_event.type = InputTypeShort;
|
||||
view_port_input(view_port, &fallback_event);
|
||||
fallback_event.type = InputTypeRelease;
|
||||
view_port_input(view_port, &fallback_event);
|
||||
}
|
||||
}
|
||||
|
||||
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
|
||||
}
|
||||
|
||||
void view_port_set_orientation(ViewPort* view_port, ViewPortOrientation orientation) {
|
||||
furi_assert(view_port);
|
||||
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
|
||||
|
||||
@@ -32,6 +32,12 @@ typedef void (*ViewPortDrawCallback)(Canvas* canvas, void* context);
|
||||
*/
|
||||
typedef void (*ViewPortInputCallback)(InputEvent* event, void* context);
|
||||
|
||||
/** ViewPort Ascii callback
|
||||
* @return true if event handled, false if event ignored
|
||||
* @warning called from GUI thread
|
||||
*/
|
||||
typedef bool (*ViewPortAsciiCallback)(AsciiEvent* event, void* context);
|
||||
|
||||
/** ViewPort allocator
|
||||
*
|
||||
* always returns view_port or stops system if not enough memory.
|
||||
@@ -88,6 +94,10 @@ void view_port_input_callback_set(
|
||||
ViewPort* view_port,
|
||||
ViewPortInputCallback callback,
|
||||
void* context);
|
||||
void view_port_ascii_callback_set(
|
||||
ViewPort* view_port,
|
||||
ViewPortAsciiCallback callback,
|
||||
void* context);
|
||||
|
||||
/** Emit update signal to GUI system.
|
||||
*
|
||||
|
||||
@@ -22,6 +22,9 @@ struct ViewPort {
|
||||
|
||||
ViewPortInputCallback input_callback;
|
||||
void* input_callback_context;
|
||||
|
||||
ViewPortAsciiCallback ascii_callback;
|
||||
void* ascii_callback_context;
|
||||
};
|
||||
|
||||
/** Set GUI reference.
|
||||
@@ -50,3 +53,12 @@ void view_port_draw(ViewPort* view_port, Canvas* canvas);
|
||||
* @param event pointer to input event
|
||||
*/
|
||||
void view_port_input(ViewPort* view_port, InputEvent* event);
|
||||
|
||||
/** Process ascii. Calls ascii callback.
|
||||
*
|
||||
* To be used by GUI, called on ascii dispatch.
|
||||
*
|
||||
* @param view_port ViewPort instance
|
||||
* @param event pointer to ascii event
|
||||
*/
|
||||
void view_port_ascii(ViewPort* view_port, AsciiEvent* event);
|
||||
|
||||
@@ -16,6 +16,7 @@ struct ViewStack {
|
||||
|
||||
static void view_stack_draw(Canvas* canvas, void* model);
|
||||
static bool view_stack_input(InputEvent* event, void* context);
|
||||
static bool view_stack_ascii(AsciiEvent* event, void* context);
|
||||
|
||||
static void view_stack_update_callback(View* view_top_or_bottom, void* context) {
|
||||
furi_assert(view_top_or_bottom);
|
||||
@@ -69,6 +70,7 @@ ViewStack* view_stack_alloc(void) {
|
||||
view_allocate_model(view_stack->view, ViewModelTypeLocking, sizeof(ViewStackModel));
|
||||
view_set_draw_callback(view_stack->view, view_stack_draw);
|
||||
view_set_input_callback(view_stack->view, view_stack_input);
|
||||
view_set_ascii_callback(view_stack->view, view_stack_ascii);
|
||||
view_set_context(view_stack->view, view_stack);
|
||||
view_set_enter_callback(view_stack->view, view_stack_enter);
|
||||
view_set_exit_callback(view_stack->view, view_stack_exit);
|
||||
@@ -121,6 +123,25 @@ static bool view_stack_input(InputEvent* event, void* context) {
|
||||
return consumed;
|
||||
}
|
||||
|
||||
static bool view_stack_ascii(AsciiEvent* event, void* context) {
|
||||
furi_assert(event);
|
||||
furi_assert(context);
|
||||
|
||||
ViewStack* view_stack = context;
|
||||
|
||||
bool consumed = false;
|
||||
ViewStackModel* model = view_get_model(view_stack->view);
|
||||
for(int i = MAX_VIEWS - 1; i >= 0; i--) {
|
||||
if(model->views[i] && view_ascii(model->views[i], event)) {
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
view_commit_model(view_stack->view, false);
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void view_stack_add_view(ViewStack* view_stack, View* view) {
|
||||
furi_assert(view_stack);
|
||||
furi_assert(view);
|
||||
|
||||
@@ -77,6 +77,8 @@ int32_t input_srv(void* p) {
|
||||
input->thread_id = furi_thread_get_current_id();
|
||||
input->event_pubsub = furi_pubsub_alloc();
|
||||
furi_record_create(RECORD_INPUT_EVENTS, input->event_pubsub);
|
||||
input->ascii_pubsub = furi_pubsub_alloc();
|
||||
furi_record_create(RECORD_ASCII_EVENTS, input->ascii_pubsub);
|
||||
|
||||
#if INPUT_DEBUG
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull);
|
||||
|
||||
@@ -12,6 +12,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define RECORD_INPUT_EVENTS "input_events"
|
||||
#define RECORD_ASCII_EVENTS "ascii_events"
|
||||
#define INPUT_SEQUENCE_SOURCE_HARDWARE (0u)
|
||||
#define INPUT_SEQUENCE_SOURCE_SOFTWARE (1u)
|
||||
|
||||
@@ -40,6 +41,48 @@ typedef struct {
|
||||
InputType type;
|
||||
} InputEvent;
|
||||
|
||||
typedef enum {
|
||||
AsciiValueNUL = 0x00, // NULL
|
||||
_AsciiValueSOH = 0x01, // Start of Heading
|
||||
_AsciiValueSTX = 0x02, // Start of Text
|
||||
_AsciiValueETX = 0x03, // End of Text
|
||||
_AsciiValueEOT = 0x04, // End of Transmission
|
||||
_AsciiValueENQ = 0x05, // Enquiry
|
||||
_AsciiValueACK = 0x06, // Acknowledgement
|
||||
_AsciiValueBEL = 0x07, // Bell
|
||||
AsciiValueBS = 0x08, // Backspace
|
||||
_AsciiValueTAB = 0x09, // Horizontal Tab
|
||||
_AsciiValueLF = 0x0A, // Line Feed
|
||||
_AsciiValueVT = 0x0B, // Vertical Tab
|
||||
_AsciiValueFF = 0x0C, // Form Feed
|
||||
AsciiValueCR = 0x0D, // Carriage Return
|
||||
_AsciiValueSO = 0x0E, // Shift Out
|
||||
_AsciiValueSI = 0x0F, // Shift In
|
||||
_AsciiValueDLE = 0x10, // Data Link Escape
|
||||
AsciiValueDC1 = 0x11, // Device Control 1
|
||||
AsciiValueDC2 = 0x12, // Device Control 2
|
||||
AsciiValueDC3 = 0x13, // Device Control 3
|
||||
AsciiValueDC4 = 0x14, // Device Control 4
|
||||
_AsciiValueNAK = 0x15, // Negative Acknowledgement
|
||||
_AsciiValueSYN = 0x16, // Synchronous Idle
|
||||
_AsciiValueETB = 0x17, // End of Transmission Block
|
||||
_AsciiValueCAN = 0x18, // Cancel
|
||||
_AsciiValueEM = 0x19, // End of Medium
|
||||
_AsciiValueSUB = 0x1A, // Substitute
|
||||
AsciiValueESC = 0x1B, // Escape
|
||||
_AsciiValueSF = 0x1C, // File Separator
|
||||
_AsciiValueGS = 0x1D, // Group Separator
|
||||
_AsciiValueRS = 0x1E, // Record Separator
|
||||
_AsciiValueUS = 0x1F, // Unit Separator
|
||||
// Printable Ascii 0x20-0x7E
|
||||
_AsciiValueDEL = 0x7F, // Delete
|
||||
} AsciiValue;
|
||||
|
||||
/** Ascii Event, dispatches with FuriPubSub */
|
||||
typedef struct {
|
||||
uint8_t value;
|
||||
} AsciiEvent;
|
||||
|
||||
/** Get human readable input key name
|
||||
* @param key - InputKey
|
||||
* @return string
|
||||
|
||||
@@ -36,6 +36,8 @@ typedef struct {
|
||||
InputPinState* pin_states;
|
||||
Cli* cli;
|
||||
volatile uint32_t counter;
|
||||
|
||||
FuriPubSub* ascii_pubsub;
|
||||
} Input;
|
||||
|
||||
/** Input press timer callback */
|
||||
|
||||
Reference in New Issue
Block a user